Spring-Boot&Security&oauth2
数据源
动态数据源
- application.properties中配置多个数据源
- 实现ImportBeanDefinitionRegister,EnviromentAware接口,初始化并出册数据源,引入SpringBootApplication注解的类中(@Import('class'))
- 创建包含ThreadLocal的类,供动态选择数据源
- 实现AbstractRoutingDataSource类,引用3中的类,决定数据源
可参考
https://www.liaoxuefeng.com/article/00151054582348974482c20f7d8431ead5bc32b30354705000
自定义注解
指定target,方式@Target(java.lang.annotaion.ElementType.*)
指定retention,方式@Retention(java.lang.annotaion.RetentionPolicy.*)
signature返回类型@interface
1通过handler绑定业务逻辑
- 通过一个实现HandlerMethodArgumentResolver的类将该注解与具体业务逻辑绑定
- 后将其在WebMvcConfigurerAdapter的实现类中通过addArgumentResolvers添加实现了HandlerMethodArgumentResolver的类
- 可参考
- https://docs.spring.io/spring/docs/5.1.0.BUILD-SNAPSHOT/javadoc-api/
- 实现不同类型的接口或抽象类绑定不同的业务逻辑
2通过aop
- @Around("@annotation(_the annotation name_)")
- 使用aop时,需要注意2点
- 1. 使用@Aspect和@Component注解创建aop类,使用@EnableAspectJAutoProxy(proxyTargetClass=true)再SpringBootApplication类中开启aop
- 2. 切入点可以直接使用或自定义切面,格式为modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?,其中ret-type-pattern name-pattern param-pattern为必须,即方法签名必须。
filter
- 可以实现HandlerInterceptor或继承HandlerInterceptorAdapter并声明为component,可以选择重写preHandler,postHandler,afterCompletion方法
- 创建类继承WebMvcConfigurerAdapter,并声明为Configuration,重写addIntecetpors添加1中拦截器
- 可参考https://docs.spring.io/spring/docs/5.1.0.BUILD-SNAPSHOT/javadoc-api/
authentication
*.config.SecurityConfig.configure(AuthenticationManagerBuilder auth)->new StandardPasswordEncoder("");
*.config.SecurityConfig.configure(HttpSecurity http);(另外还有可以定义在方法级的注解授权,如:
@PreAuthorize("hasRole('USER')")
可参考https://docs.spring.io/spring-security/site/docs/4.1.3.RELEASE/reference/htmlsingle/#method-security-meta-annotations)
oauth2(类似单点登录)
服务端
- 服务端提供验证服务uri,添加oauth2依赖
客户端
- application中配置验证uri,即authentication
- 不同于security的是实现继承WebSecurityConfigurerAdapter,并配置权限,即authorization
- 自动配置单一验证服务器时使用@EnableOauth2Sso;手动配置验证服务器时使用@EnableOauth2Client
- 自定义验证拦截器结构可以如下:
1. 使用@Bean生成每个验证服务源的信息类,注入context中;其中指定每个验证服务源时,可使用@ConfigurationProperties('指定application.[properties,yml]中的单一验证服务源的前缀值';
2. 定义生成filter的类,其中
OAuth2ClientAuthenticationProcessingFilter facebookFilter = new OAuth2ClientAuthenticationProcessingFilter("url");//绑定url
OAuth2RestTemplate facebookTemplate = new OAuth2RestTemplate('AuthorizationCodeResourceDetails', oauth2ClientContext);//生成绑定指定验证服务源和应用上下文的OAuth2RestTemplate
facebookFilter.setRestTemplate(facebookTemplate);将生成的template注入filter
UserInfoTokenServices tokenServices = new UserInfoTokenServices(facebookResource().getUserInfoUri(),facebook().getClientId());//生成指定验证服务源的tokenservices tokenServices.setRestTemplate(facebookTemplate);//为token services绑定template
facebookFilter.setTokenServices(new UserInfoTokenServices(facebookResource().getUserInfoUri(), facebook().getClientId()));//将token services注入filter
- 创建List<Filter>并添加2中生成的Filter,创建CompositerFilter并添加上一步生成的List<Filter>;重写void configure(HttpSecurity http)时,添加http.addFilterBefore(’4中生成的CompositerFilter‘,BaseAuthenticationFilter.class)
-
@Bean
public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<OAuth2ClientContextFilter>();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
作用类似5,直接向上下文中注入
-
验证后,针对用户的业务逻辑
1. 定义方法接受OAuth2RestOperations参数返回AuthoritiesExtractor,并使用@Bean注人,参数为验证服务器返回信息,处理后选择是否抛出异常
2. @Configuration
protected static class ServletCustomizer {
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> customizer() {
return container -> { container.addErrorPages(new ErrorPage(HttpStatus.UNAUTHORIZED, "/unauthenticated"));//定义服务异常后定向的url };
} }