首页 > 编程语言 > 详细

spring cloud oauth2 授权服务搭建

时间:2021-02-03 18:02:17      阅读:24      评论:0      收藏:0      [点我收藏+]

依赖
注:使用的springboot版本 2.2.4.RELEASE ;spring cloud 版本 Hoxton.SR1
加入oauth2和web相关的依赖

org.springframework.boot
spring-boot-starter-web

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
    </dependency>

集成步骤
? 继承WebSecurityConfigurerAdapter 配置security相关配置
? 继承AuthorizationServerConfigurerAdapter 配置授权服务
? 实现UserDetailsService ,查询客户信息
WebSecurityConfig配置
package com.Lonni.oauth.config;
import cn.hutool.crypto.digest.DigestUtil;
import com.Lonni.oauth.exception.filter.CustomOncePerRequestFilter;
import com.Lonni.oauth.provider.MobileCodeAuthenticationProvider;
import com.Lonni.oauth.service.UserDetailsServiceImpl;
import org.apache.tomcat.util.digester.Digester;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.header.HeaderWriterFilter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 查询客户端是需要用这个加解密 而不是原始的
* @return
/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/
*
* 配置redis
/
@Autowired
private RedisTemplate redisTemplate;
/
*
* 查询用户信息
/
@Autowired
private UserDetailsServiceImpl userDetailsService;
/
*
* 配置密码模式需要的AuthenticationManager
* @return
* @throws Exception
/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
AuthenticationManager manager = super.authenticationManagerBean();
return manager;
}
/
*
* 这里是对认证管理器的添加配置
*
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth

            //设置查询的userDetailsService
            .userDetailsService(userDetailsService)
            //设置密码加密器 设置为自定义工具类 而不是使用security自带的
            .passwordEncoder(new PasswordEncoder() {
                @Override
                public String encode(CharSequence charSequence) {
                    String mdStr = DigestUtil.sha1Hex((String) charSequence);
                    return mdStr;
                }
                @Override
                public boolean matches(CharSequence charSequence, String encodedPassword) {
                    return encodedPassword.equals(DigestUtil.sha1Hex((String) charSequence));
                }
            });
}
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
            .authorizeRequests()
            .anyRequest().permitAll()
            .and()
            .formLogin()
            .and()
            .logout();
  
}

}
.passwordEncoder方法设置在查询用户时密码比对的加密器;可根据自己的需要替换
配置 AuthorizationServerConfigurerAdapter 服务
? 配置jwt token配置类
? 配置jwt token增强器
? 配置server配置
jwt token配置类
package com.Lonni.core.aouth2.config;
import com.Lonni.common.constants.AuthConstant;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
/**

  • @program: Lonni-plus
  • @description: jwttoken配置类
  • @author: lonni
  • @create: 2020-11-19 21:18
    /
    @Configuration
    public class JwtTokenConfig {
    /
    *
    • 1:配置 JWT 数据转换
    • 设置解密的key
    • @return
      /
      @Bean("jwtAccessTokenConverter")
      public JwtAccessTokenConverter jwtAccessTokenConverter(){
      JwtAccessTokenConverter converter=new JwtAccessTokenConverter();
      //设置为解密token的key 同样在加密的时候也要设置为这个key
      converter.setSigningKey(AuthConstant.AUTH_SECURITY_JWT_SIGN_KEY);
      return converter;
      }
      /
      *
    • 2:返回jwt存储器
    • @return
      /
      @Bean("jwtTokenStore")
      public TokenStore jwtTokenStore(){
      return new JwtTokenStore(jwtAccessTokenConverter());
      }
      }
      配置jwt token增强器,在生成token时增加额外信息
      package com.Lonni.oauth.config;
      import com.Lonni.common.constants.AuthConstant;
      import com.Lonni.oauth.model.CustomUserDetails;
      import com.Lonni.oauth.utils.PrincipalUtil;
      import com.alibaba.fastjson.JSON;
      import com.google.common.collect.Maps;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken;
      import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
      import org.springframework.security.oauth2.common.OAuth2AccessToken;
      import org.springframework.security.oauth2.provider.OAuth2Authentication;
      import org.springframework.security.oauth2.provider.token.TokenEnhancer;
      import java.security.Principal;
      import java.util.Calendar;
      import java.util.Date;
      import java.util.HashMap;
      import java.util.Map;
      /
      *
  • 增强jwt使用
    /
    public class JWTokenEnhancer implements TokenEnhancer {
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {
    //password,mobile,captcha
    String grantType = oAuth2Authentication.getOAuth2Request().getGrantType();
    //生成jwt时不会生成所有的信息 需要自己存入
    if ("password".equals(grantType) || "mobile".equals(grantType) || "captcha".equals(grantType)) {
    Object principal = oAuth2Authentication.getPrincipal();
    //登录成功后就是cus
    CustomUserDetails userDetails = (CustomUserDetails) principal;
    Map<String, Object> info = new HashMap<>();
    //在这里扩展信息
    info.put("userId", userDetails.getUserId());
    info.put("userName", userDetails.getUsername());
    info.put("nickName", userDetails.getNickName());
    info.put("phone", userDetails.getPhone());
    info.put("openId", userDetails.getOpenId());
    info.put("unionId", userDetails.getUnionId());
    info.put("avatar", userDetails.getAvatar());
    DefaultOAuth2AccessToken auth2AccessToken = ((DefaultOAuth2AccessToken) oAuth2AccessToken);
    auth2AccessToken.setAdditionalInformation(info);
    //如果是client_id=app 过时时间为5天
    String clientId = oAuth2Authentication.getOAuth2Request().getClientId();
    if (AuthConstant.AUTH_APPLICATION_APP_ID.equals(clientId)) {
    Calendar calen = Calendar.getInstance();
    calen.add(Calendar.DAY_OF_YEAR, 5);
    auth2AccessToken.setExpiration(calen.getTime());
    }
    }
    return oAuth2AccessToken;
    }
    }
    注意 : oAuth2Authentication.getPrincipal()如果是授权码模式或则客户端模式获取的时候就不是用户的信息,需要判断授权模式才转换
    配置server
    package com.Lonni.oauth.config;
    import com.Lonni.common.constants.AuthConstant;
    import com.Lonni.oauth.exception.filter.CustomAuthenticationEntryPoint;
    import com.Lonni.oauth.exception.filter.CustomClientCredentialsTokenEndpointFilter;
    import com.Lonni.oauth.granter.TokenGranterExt;
    import com.Lonni.oauth.service.UserDetailsServiceImpl;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
    import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
    import org.springframework.security.oauth2.provider.ClientDetailsService;
    import org.springframework.security.oauth2.provider.TokenGranter;
    import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
    import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
    import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
    import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
    import org.springframework.security.oauth2.provider.token.
    ;
    import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
    import javax.sql.DataSource;
    import java.util.ArrayList;
    import java.util.List;
    /**
  • 配置认证服务文件
    /
    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    /
    *
    • AuthenticationManager authenticationManager ;认证管理器;如果为password模式时必须配置
    • AuthorizationCodeServices authorizationCodeServices ;如果是授权码模式,必须设置此对象
    • ImplicitGrantService implicitGrantService;如果是ImplicitG模式 需要设置此对象
    • 访问资源服务器:
    • 在header头中加上
    • Authorization: Bearer 你的token值
      /
      /
      *
    • 如果是密码模式 必须配置
      /
      @Autowired
      AuthenticationManager authenticationManager;
      /
      *
    • 密码加密器 新版本必须配置
      /
      @Autowired
      PasswordEncoder passwordEncoder;
      @Autowired
      private ClientDetailsService clientDetailsService;
      @Autowired
      private UserDetailsServiceImpl userDetailsService;
      @Autowired
      private RedisTemplate redisTemplate;
      /
      **
    • 将客户端信息存储到数据库
    • 1:配置数据库连接
    • 2:注入DataSource
    • 3:初始化ClientDetailsService 这里直接在config方法中返回jdbcclient
    • 4:修改configure(ClientDetailsServiceConfigurer clients)方法 ,使用数据库方式
    • 5:修改授权码实现类 AuthorizationCodeServices 为数据库方式
    /
    @Autowired
    private DataSource dataSource;
    /
    *
    • 1: 配置客户端的方法
    • @param clients
    • @throws Exception
      /
      @Override
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
      //配置客户端存储到db
      JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
      //设置客户端的密码对比加密器
      clientDetailsService.setPasswordEncoder(passwordEncoder);
      //设置查询的sql
      clientDetailsService.setFindClientDetailsSql(AuthConstant.FIND_CLIENT_DETAILS_SQL);
      clientDetailsService.setSelectClientDetailsSql(AuthConstant.SELECT_CLIENT_DETAILS_SQL);
      clients.withClientDetails(clientDetailsService);
      }
      // 注入 TokenStore 使用 jwt方式 在jwtTokenConfig中配置了
      @Autowired
      @Qualifier("jwtTokenStore")
      private TokenStore tokenStore;
      // 注入 jwt token 转换器 在jwtTokenConfig中配置了
      @Autowired
      @Qualifier("jwtAccessTokenConverter")
      private JwtAccessTokenConverter jwtAccessTokenConverter;
      @Bean
      public TokenEnhancer jwtTokenEnhancer() {
      return new JWTokenEnhancer();
      }
      /
      *
    • 3 配置令牌服务 不管什么服务 都需要此配置
    • @return
      /
      @Bean
      public AuthorizationServerTokenServices tokenServices() {
      DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
      //配置客户端信息服务
      defaultTokenServices.setClientDetailsService(clientDetailsService);
      //配置客户端令牌存储策略
      defaultTokenServices.setTokenStore(tokenStore);
      //是否产生刷新令牌 如果是jdbc方式 需要在数据库中设置,在这里设置无效
      defaultTokenServices.setSupportRefreshToken(true);
      //令牌的有效期 2小时
      defaultTokenServices.setAccessTokenValiditySeconds(7200);
      //刷新令牌的有效期 3天
      defaultTokenServices.setRefreshTokenValiditySeconds(259200);
      // 配置 token 转换器 jwt方式必须配置
      //配置token增加,把一般token转换为jwt token
      TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
      List enhancerList = new ArrayList<>();
      enhancerList.add(jwtTokenEnhancer());
      enhancerList.add(jwtAccessTokenConverter);
      tokenEnhancerChain.setTokenEnhancers(enhancerList);
      defaultTokenServices.setTokenEnhancer(tokenEnhancerChain);
      return defaultTokenServices;
      }
      /
      *
    • 4配置授权服务器的终结点和其他属性
    • 令牌访问端点
    • @param endpoints
    • @throws Exception
      /
      @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
      endpoints
      //设置密码模式认证器
      .authenticationManager(authenticationManager)
      //设置授权码模式认证器
      .authorizationCodeServices(this.authorizationCodeServices())
      //设置令牌策略
      .tokenServices(tokenServices())
      //设置查询用户的userDetilService
      .userDetailsService(userDetailsService)
      //允许post get提交认证
      .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
      ;
      }
      /
      *
    • 配置授权码服务的实现类 数据库方式
    • @return
      /
      @Bean
      public AuthorizationCodeServices authorizationCodeServices() {
      return new JdbcAuthorizationCodeServices(dataSource);
      }
      /
      *
    • 5令牌访问的安全策略
    • @param security
    • @throws Exception
      */
      @Override
      public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
      security
      // 即clientId和clientSecret组合起来base加密后放在http header中传递
      // .allowFormAuthenticationForClients()
      //oauth/token_key是公开
      .tokenKeyAccess("permitAll()")
      //oauth/check_token公开
      .checkTokenAccess("permitAll()")
      ;
      }
      }

spring cloud oauth2 授权服务搭建

原文:https://www.cnblogs.com/HiLzd/p/14367744.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!