1、@EnableOAuth2Client:客户端,提供OAuth2RestTemplate,用于客户端访问资源服务。
简要步骤:客户端访问资源->客户端发现没有资源访问token->客户端根据授权类型生成跳转url->浏览器 302 到认证授权服务进行认证、授权。
2、@EnableOAuth2Sso:应用系统,使用远端认证授权服务,替换应用自身的用户登录鉴权security逻辑,实现单点登录功能。
简要步骤:访问应用系统资源-> 应用系统发现未登录-> 302 跳转到登录页面(登录页面地址已经与获取token逻辑自动关联)-> 应用系统发现符合获取token条件,根据授权类型拼装url->302 跳转到认证授权地址(认证授权服务提供)进行认证、授权。
3、@EnableAuthorizationServer:认证授权服务,提供用于获取token,解析token相关功能,实现认证、授权功能。
具体见 Spring Security 文章目录中的 Spring Cloud OAuth2 五种授权方式介绍。
4、@EnableResourceServer:资源服务,提供基于token的资源访问功能。
<--认证服务器配置--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-security</artifactId> </dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId> </dependency>
@Configuration @EnableAuthorizationServer public class OAuth2Config extends AuthorizationServerConfigurerAdapter {@Autowiredprivate DataSource dataSource;@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate RedisConnectionFactory redisConnectionFactory;@Autowiredprivate CodeStoreService codeStoreService;@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security.allowFormAuthenticationForClients().tokenKeyAccess("isAuthenticated()").checkTokenAccess("isAuthenticated()");}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.jdbc(dataSource).passwordEncoder(passwordEncoder);}@Beanpublic JwtTokenStore jwtTokenStore() {return new JwtTokenStore(jwtAccessTokenConverter());}@Beanpublic RedisTokenStore redisTokenStore() {return new RedisTokenStore(redisConnectionFactory);}@Beanpublic AuthorizationServerTokenServices authorizationServerTokenServices() {DefaultTokenServices defaultTokenServices = new DefaultTokenServices();defaultTokenServices.setTokenStore(redisTokenStore());defaultTokenServices.setSupportRefreshToken(true);defaultTokenServices.setRefreshTokenValiditySeconds(30 * 60 * 1000);defaultTokenServices.setAccessTokenValiditySeconds(30 * 69 * 1000);return defaultTokenServices;}@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter() {ClassPathResource resource = new ClassPathResource("user.jks");KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource, "123456".toCharArray());JwtAccessTokenConverter jwtTokenConverter = new JwtAccessTokenConverter();jwtTokenConverter.setKeyPair(keyStoreKeyFactory.getKeyPair("xm"));return jwtTokenConverter;}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.allowedTokenEndpointRequestMethods(HttpMethod.POST);endpoints.authenticationManager(authenticationManager);//endpoints.accessTokenConverter(jwtAccessTokenConverter());endpoints.tokenServices(authorizationServerTokenServices());endpoints.authorizationCodeServices(codeStoreService);} }
spring security 的配置文件
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate CustomUserDetailsService userDetailsService;@Autowiredprivate SuccessAuthentication successAuthentication;@Autowiredprivate FailureAuthentication failureAuthentication;@Autowiredprivate UnauthorizedEntryPoint unauthorizedEntryPoint;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);}@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Overridepublic void configure(WebSecurity web) {web.ignoring().mvcMatchers("/assets/**", "/css/**", "/images/**");}@Overrideprotected void configure(HttpSecurity http) throws Exception {/*http.csrf().disable();http.authorizeRequests().antMatchers( "/oauth/token", "/check/token").permitAll();http.authorizeRequests().antMatchers("/success").hasRole("USER").antMatchers("/success").hasRole("ADMIN").antMatchers("/user/r1").hasRole("USER").antMatchers("/user/r2").hasRole("ADMIN").antMatchers("/user/p1").hasAuthority("p1").antMatchers("/user/p2").hasAuthority("p2").anyRequest().authenticated().and().formLogin().loginPage("/login").successForwardUrl("/success").and().exceptionHandling().accessDeniedHandler(new CustomAccessDecisionHandler()).and().httpBasic();*/http.csrf().disable();http.formLogin().loginPage("/login")//.successHandler(successAuthentication)//.failureHandler(failureAuthentication).and().authorizeRequests().antMatchers("/login").permitAll().anyRequest().authenticated().and()/*.exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint).and()*/.rememberMe(remember ->remember.rememberMeParameter("remember-me").rememberMeCookieName("remember-me").tokenValiditySeconds(30 * 1000).userDetailsService(userDetailsService));} }
资源服务器使用spring-boot-starter-oauth2-client
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-resource-server</artifactId></dependency><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity5</artifactId><version>3.0.4.RELEASE</version> </dependency>
spring.security.oauth2.client.registration.user.provider=user spring.security.oauth2.client.registration.user.client-id=user-service spring.security.oauth2.client.registration.user.client-secret=root spring.security.oauth2.client.registration.user.authorization-grant-type=authorization_code spring.security.oauth2.client.registration.user.redirect-uri=http://localhost:9091/login spring.security.oauth2.client.registration.user.scope=all spring.security.oauth2.client.provider.user.authorization-uri=http://localhost:9091/oauth/authorize spring.security.oauth2.client.provider.user.token-uri=http://localhost:9091/oauth/token spring.security.oauth2.client.provider.user.user-info-uri=http://localhost:9091/oauth2/userinfo spring.security.oauth2.client.provider.user.user-name-attribute=sub spring.security.oauth2.client.provider.user.jwk-set-uri=http://localhost:9091/oauth/token_key spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:9091/oauth/token_key
@EnableWebSecurity @Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated();http.oauth2ResourceServer(oauth2->oauth2.jwt());// 改成oauth2Login 就是oauth 登录} }
参考资料
https://www.cnblogs.com/atwood-pan/p/17787904.html
OAuth2 - @EnableResourceServer vs @EnableOAuth2Sso | Baeldung
Spring-Security-OAuth2-Client | zyc的博客
spring oauth2实现单点登录,Vue+spring boot+oauth2前后端分离 - 简书
(二)、Spring Security OAuth2 四个常用注解说明_oauth2clientcontext是什么-CSDN博客
https://www.cnblogs.com/atwood-pan/p/17787904.html
springsecurity oauth2实现前后端分离项目的SSO技术点总结_spring outh2 前后端分离-CSDN博客
【Spring Security OAuth2 Client】基本介绍以及定制开发_spring-boot-starter-oauth2-client-CSDN博客
springboot整合Oauth2_spring-boot-starter-oauth2-client-CSDN博客
https://www.cnblogs.com/simpleito/p/15786122.html
自定义grant_type 以及第三方登录。
总之,这个东西比较复杂,暂且放过