SpringSecurity+OAuth2.0+JWT实现用户认证中心

随着公司资源,市场,以及深圳部分业务拓展,公司希望将公司所有的用户信息进行整合,搭建一个统一平台,用来支持各业务线的用户授权认证,方便其他子公司授权后获取资源系统的资源,最后经过讨论,决定采用Springsecurity+Oauth2.0+JWT来实现用户认证中心。

OAuth2.0

oauth2.0是一种授权机制,由第三方向资源所有者请求授权,资源所有者同意授权后,第三方去授权服务器获取令牌,资源服务器发放令牌,第三方使用令牌去访问资源服务器的资源。资源服务器校验token无误后开放资源。流程如下图所示

OAuth2.0一共包含四种授权模式:授权码,隐藏式,密码式,凭证式

关于这一部分内容可以参考阮一峰老师的:http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html 讲的非常的详细

JWT

  在token方面,普通的token需要查库或者内存验证token 是否有效,而JWT不用查库或者少查库,直接在服务端进行校验,并且不用查库。因为用户的信息及加密信息在第二部分payload和第三部分签证中已经生成,只要在服务端进行校验就行,并且校验也是JWT自己实现的。而且第二部分payload可以拓展自己的业务信息,比如用户权限等。

具体实现:

/**
 * OAuth2 配置文件
 *
 * @author yangle
 * @date 2020-06-15 14:44
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {

  @Autowired
  public PasswordEncoder passwordEncoder;

  @Autowired
  public UserService userService;

  @Autowired
  private AuthenticationManager authenticationManager;

  @Autowired
  private DataSource dataSource;

  @Autowired
  private TokenStore jwtTokenStore;

  @Autowired
  private JwtAccessTokenConverter jwtAccessTokenConverter;

  @Override
  public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints
        //token存储方式
        .tokenStore(jwtTokenStore)
        //token转换方式使用jwt
        .accessTokenConverter(jwtAccessTokenConverter)
        //用户验证
        .userDetailsService(userService)
        //支持password模式
        .authenticationManager(authenticationManager);
  }

  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    //定义客户端约束条件,这里采用数据库方式配置
    JdbcClientDetailsServiceBuilder jdbc = clients.jdbc(dataSource);
    //指定加密方式
    jdbc.passwordEncoder(passwordEncoder);
  }

  @Override
  public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    //允许客户端访问 OAuth2.0 授权接口
    security.allowFormAuthenticationForClients();
    //允许已授权用户访问 checkToken 接口
    security.checkTokenAccess("isAuthenticated()");
    //允许已授权用户访问 获取 token 接口
    security.tokenKeyAccess("isAuthenticated()");
  }
}
AuthorizationServerConfigurer类继承AuthorizationServerConfigurerAdapter,重写里面三个configure方法。
/**
 * spring security 基础配置
 *
 * @author yangle
 * @date 2020-06-15 14:04
 */
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/**").permitAll();
  }
}
WebSecurityConfig类继承WebSecurityConfigurerAdapter,主要用于spring security 基础配置,关于这块详细的配置可以去学习下spring security,这里侧重点是为了用户认证,没有详细去写。
/**
 *  Jwt配置类
 *
 * @author yangle
 * @date 2020-06-15 14:47
 */
@Configuration
public class JwtTokenConfig {

  @Bean
  public TokenStore jwtTokenStore() {
    return new JwtTokenStore(jwtAccessTokenConverter());
  }

  @Bean
  public JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
    accessTokenConverter.setSigningKey("token");
    return accessTokenConverter;
  }

}
Jwt配置类,这里需要注意客服端签名应该与授权服务器签名一致
/**
 * 实现 UserDetailsService
 *
 * @author yangle
 * @date 2020-06-15 14:06
 */
@Component
public class UserService implements UserDetailsService {

  private Logger log = LoggerFactory.getLogger(getClass());

  @Autowired
  private UserInfoService userInfoService;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    log.info("username is:" + username);

    UserInfo userInfo = userInfoService.getUserInfoByUsername(username);
    if (userInfo == null) {
      throw new UsernameNotFoundException("the user is not found");
    }
    List<SimpleGrantedAuthority> authorities = new ArrayList<>();
    //此处可以根据自己的业务添加权限,这里就写死了
    authorities.add(new SimpleGrantedAuthority("admin"));
    return new org.springframework.security.core.userdetails.User(username, userInfo.getPassword(),
        authorities);
  }
}
UserService实现UserDetailsService,该类是实现Springsecurity用户身份验证的一种简单方式,结合 AuthenticationProvider
的方式可以自行去了解学习下Springsecurity。

以上是比较重要的代码,userInfoService这个类就不在这里说了,就是简单的去数据库进行查找。

github地址:https://github.com/jcyangl/Spring-Security-oauth2.0

猜你喜欢

转载自blog.csdn.net/qq_33302985/article/details/106765557
今日推荐