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 { @Autowired private DataSource dataSource; @Autowired private AuthenticationManager authenticationManager; @Autowired private PasswordEncoder passwordEncoder; @Autowired private RedisConnectionFactory redisConnectionFactory; @Autowired private CodeStoreService codeStoreService; @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.allowFormAuthenticationForClients().tokenKeyAccess("isAuthenticated()") .checkTokenAccess("isAuthenticated()"); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource).passwordEncoder(passwordEncoder); } @Bean public JwtTokenStore jwtTokenStore() { return new JwtTokenStore(jwtAccessTokenConverter()); } @Bean public RedisTokenStore redisTokenStore() { return new RedisTokenStore(redisConnectionFactory); } @Bean public AuthorizationServerTokenServices authorizationServerTokenServices() { DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); defaultTokenServices.setTokenStore(redisTokenStore()); defaultTokenServices.setSupportRefreshToken(true); defaultTokenServices.setRefreshTokenValiditySeconds(30 * 60 * 1000); defaultTokenServices.setAccessTokenValiditySeconds(30 * 69 * 1000); return defaultTokenServices; } @Bean public 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; } @Override public 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 { @Autowired private PasswordEncoder passwordEncoder; @Autowired private CustomUserDetailsService userDetailsService; @Autowired private SuccessAuthentication successAuthentication; @Autowired private FailureAuthentication failureAuthentication; @Autowired private UnauthorizedEntryPoint unauthorizedEntryPoint; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override public void configure(WebSecurity web) { web.ignoring().mvcMatchers("/assets/**", "/css/**", "/images/**"); } @Override protected 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 { @Override protected 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 以及第三方登录。
总之,这个东西比较复杂,暂且放过