Springboot整合Oauth2.0+jwt

说明:使用password认证模式

jwt提供算法,JwtTokenStore不存储token值,若要存储(Redis)token需要自己额外写token存储及过期和刷新逻辑

1.Oauth配置 

声明类
//Oauth2.0配置类
public class OAuth2AuthorizationServeConfig  extends AuthorizationServerConfigurerAdapter
//SpringSecurity配置类
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
//ResourceServer资源配置类
public class ResourceServerConfig extends ResourceServerConfigurerAdapter
//用户信息查询类
public class RenUserDetailsServiceImpl implements UserDetailsService{
    @Override
    public User loadUserByUsername(String username) throws UsernameNotFoundException{
        //查询用户逻辑
        return new User();
    }
}

1.客户端配置

    
    @Autowired
    private PasswordEncoder passwordEncoder;
    /**
     * 默认的 oauth client_id
     */
    public static final String defaultClientId = "coreclientcomponent";
    /**
     * 默认的 oauth client_secret
     */
    public static final String defaultClientSecret = "@CoreRoot305140704202.";
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
        builder
            .withClient(defaultClientId)
            .secret(passwordEncoder.encode(defaultClientSecret))
            .scopes("all")
            .authorizedGrantTypes("password", "refresh_token","smsCode_type")
            .accessTokenValiditySeconds(21600)
            .refreshTokenValiditySeconds(86400);
    }

2.认证服务配置

    
    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;
    /**
     * token增加额外信息
     * @return
     */
    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new RenTokenEnhancer();
    }

    /**
     * Token存储使用Redis:位置:token.TokenStoreConfig
     */
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private UserDetailsService userDetailsService;
    /**
     * AuthenticationManager
     * 是一个用来处理认证(Authentication)请求的接口。在其中只定义了一个方法authenticate(),该方法只接收一个代表认证请求的Authentication对象作为参数,
     * 如果认证成功,则会返回一个封装了当前用户权限等信息的Authentication对象进行返回。
     */
    @Autowired
    private AuthenticationManager authenticationManager; 
    /**
     * AuthorizationServerEndpointsConfigurer其实是一个装载类,装载Endpoints所有相关的类配置
     * (AuthorizationServer、TokenServices、TokenStore、ClientDetailsService、UserDetailsService)。
     * @param endpoints
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST, HttpMethod.DELETE);
        //密码模式
        endpoints.authenticationManager(authenticationManager);

        //支持刷新令牌
        endpoints.userDetailsService(userDetailsService);
        //令牌管理
        endpoints.tokenStore(tokenStore);
        //令牌增强
        endpoints.tokenEnhancer(tokenEnhancer());
        //token管理
        endpoints.tokenServices(getTokenStore(endpoints));
        //token解析
        endpoints.accessTokenConverter(jwtAccessTokenConverter);
    }
      /**
     * 配置TokenService参数
     * @param endpoints
     * @return
     */
    private DefaultTokenServices getTokenStore(AuthorizationServerEndpointsConfigurer endpoints) {
        //整合jwt令牌增强
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> tokenEnhancers = new ArrayList<>();
        tokenEnhancers.add(jwtAccessTokenConverter);
        tokenEnhancers.add(tokenEnhancer());
        tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);

        DefaultTokenServices tokenService = new DefaultTokenServices();
        tokenService.setTokenStore(endpoints.getTokenStore());
        tokenService.setSupportRefreshToken(true);
        //使用jwttoken
        tokenService.setTokenEnhancer(tokenEnhancerChain);
        //token有效期 1小时
        tokenService.setAccessTokenValiditySeconds(21600);
        //token刷新有效期 15天
        tokenService.setRefreshTokenValiditySeconds(3600 * 12 * 15);
        tokenService.setReuseRefreshToken(false);
        return tokenService;
    }
    /**
     * AuthorizationServerSecurityConfigurer
     * 继承自SecurityConfigurerAdapter,
     * 也就是一个 Spring Security安全配置提供给AuthorizationServer去配置AuthorizationServer的端点(/oauth/****)的安全访问规则、过滤器Filter。
     * /oauth/authorize:授权端点
     * /oauth/token:令牌端点
     * /oauth/confirm_access:用户确认授权提交端点
     * /oauth/error:授权服务错误信息端点
     * /oauth/check_token:用于资源服务访问的令牌解析端点
     * /oauth/token_key:提供公有密匙的端点,如果使用JWT令牌的话
     * @param security
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security
                //允许用户表单认证
                .allowFormAuthenticationForClients()
                //匿名可访问/oauth/token_key
                .tokenKeyAccess("permitAll()")
                //认证后可访问/oauth/check_token
                .checkTokenAccess("isAuthenticated()")
        ;
    }
/**
 * 令牌
 *  TokenEnhancer 是 Spring Security OAuth2 中的一个接口,用于在 OAuth2 的令牌(Token)生成或解析过程中进行增强操作。
 * @author Rossi
 */
public class RenTokenEnhancer implements TokenEnhancer {
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        //在token中存储额外信息

        return accessToken;
    }
}
@Configuration
public class JwtTokenStoreConfig {

    /**
     * 自己的算法key值
     */
    private String secretKey = "******";

    @Bean
    public TokenStore tokenStore() {
        //将用户信息存储在token中,性能更快
        return new JwtTokenStore(jwtAccessTokenConverter());
    }
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(secretKey);
        return converter;
    }
}

2.SpringSecurity配置

    @Autowired
    private SysUserService sysUserService;
    /**
     * 登录验证码登录
     */
    @Resource
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    /**
     * 密码模式需要
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception{
        return super.authenticationManager();
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers(HttpMethod.OPTIONS);
    }

3.ResourceServer配置

    @Override
    public void configure(HttpSecurity http) throws Exception {
       http
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                    .authorizeRequests()
                    .antMatchers("/oauth/token").permitAll()
                    .anyRequest().authenticated().and().csrf().disable();

        http.headers().frameOptions().sameOrigin().and().httpBasic();
    }

Spring Boot可以与OAuth 2.0协议进行整合,实现授权和认证功能。下面是一些步骤: 1. 配置pom.xml文件,添加Spring Security OAuth2依赖。 ``` <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>2.3.7.RELEASE</version> </dependency> ``` 2. 配置application.properties文件,添加OAuth2配置。 ``` # OAuth2 configuration security.oauth2.client.client-id=client-id security.oauth2.client.client-secret=client-secret security.oauth2.client.access-token-uri=https://example.com/oauth/token security.oauth2.client.user-authorization-uri=https://example.com/oauth/authorize security.oauth2.client.scope=read,write security.oauth2.client.grant-type=authorization_code security.oauth2.resource.token-info-uri=https://example.com/oauth/check_token security.oauth2.resource.user-info-uri=https://example.com/userinfo ``` 3. 创建一个OAuth2客户端,用于向授权服务器发送请求并获取访问令牌。 ``` @Configuration @EnableOAuth2Sso public class OAuth2ClientConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/login**", "/error**") .permitAll() .anyRequest() .authenticated() .and() .logout() .logoutSuccessUrl("/") .permitAll() .and() .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); } @Bean public OAuth2RestTemplate oauth2RestTemplate(OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context) { return new OAuth2RestTemplate(resource, context); } @Bean @ConfigurationProperties("security.oauth2.client") public OAuth2ProtectedResourceDetails oauth2RemoteResource() { return new AuthorizationCodeResourceDetails(); } @Bean public FilterRegistrationBean oauth2ClientFilterRegistration( OAuth2ClientContextFilter filter) { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(filter); registration.setOrder(-100); return registration; } } ``` 4. 创建一个OAuth2资源服务器,用于保护受保护的资源。 ``` @Configuration @EnableResourceServer public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/**") .authenticated(); } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.resourceId("my-resource-id"); } } ``` 5. 创建一个授权服务器,用于颁发访问令牌。 ``` @Configuration @EnableAuthorizationServer public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Autowired private BCryptPasswordEncoder passwordEncoder; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("client-id") .secret(passwordEncoder.encode("client-secret")) .authorizedGrantTypes("authorization_code", "refresh_token") .scopes("read", "write") .accessTokenValiditySeconds(3600) .refreshTokenValiditySeconds(7200) .redirectUris("http://localhost:8080/login/oauth2/code/my-client"); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager) .userDetailsService(userDetailsService); } } ``` 以上是整合OAuth2.0的一些步骤和代码示例。需要注意的是,OAuth2.0是一个复杂的协议,需要深入理解和熟练掌握。同时,需要根据实际业务需求进行相应的配置和开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值