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 以及第三方登录。
总之,这个东西比较复杂,暂且放过