springsecurity oauth中认证服务器
- 2020-12-24 10:50:00
- admin 原创
- 84
springsecurity 认证服务器和资源服务器
springsecurity配置:
项目地址:https://github.com/liujiawan/springSecurity-example
/** * 安全配置类 * @author: GL * @program: springSecurity-example * @create: 2020年 06月 05日 11:01 **/ // 包含了 @Configuration 注解 @EnableWebSecurity public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService customUserDetailsService; /** * 认证管理器: * 1、认证信息提供方式(用户名、密码、当前用户的资源权限) * 2、可采用内存存储方式,也可能采用数据库方式等 * @param auth * @throws Exception */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 内存方式存储用户信息 // auth.inMemoryAuthentication().withUser("admin") // .password(passwordEncoder.encode("1234556")).authorities("product"); // 使用数据库查询的方式 auth.userDetailsService(customUserDetailsService); } /** * 密码模式需要用到这个认证管理器 * @return * @throws Exception */ @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); }2、认证服务器设置
/** * 安全配置类 * @author: GL * @program: springSecurity-example * @create: 2020年 06月 05日 11:01 **/ // 包含了 @Configuration 注解 @EnableWebSecurity public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService customUserDetailsService; /** * 认证管理器: * 1、认证信息提供方式(用户名、密码、当前用户的资源权限) * 2、可采用内存存储方式,也可能采用数据库方式等 * @param auth * @throws Exception */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 内存方式存储用户信息 // auth.inMemoryAuthentication().withUser("admin") // .password(passwordEncoder.encode("1234556")).authorities("product"); // 使用数据库查询的方式 auth.userDetailsService(customUserDetailsService); } /** * 密码模式需要用到这个认证管理器 * @return * @throws Exception */ @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); }3、密码设置:
@Configuration public class PasswordEncoderBean { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }4、token加强
@Component public class CustomTokenEnhancer implements TokenEnhancer { @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { SysUser user = (SysUser)authentication.getPrincipal(); final Map<String, Object> additionalInfo = new HashMap<>(); additionalInfo.put("userId",user.getId()); additionalInfo.put("userName",user.getNickName()); ((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(additionalInfo); return accessToken; } }5、token工具
@Configuration public class TokenConfig { /** * Redis 管理令牌 * 添加redis 依赖后, 容器就会有 RedisConnectionFactory 实例 */ @Autowired private RedisConnectionFactory redisConnectionFactory; /** * jdbc管理token * @return */ @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource dataSource(){ return new DruidDataSource(); } /** * 访问令牌的转换器 * @return */ @Bean public JwtAccessTokenConverter jwtAccessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); // 对称加密进行签名令牌,资源服务器也要采用此密钥来进行解密,来校验令牌合法性 converter.setSigningKey("abcdefg"); // 采用非对称加密jwt // 第1个参数就是密钥证书文件,第2个参数 密钥口令(-keypass), 私钥进行签名 // KeyStoreKeyFactory factory = new KeyStoreKeyFactory( // new ClassPathResource("oauth2.jks"), "oauth2".toCharArray()); // 指定非对称加密 oauth2 别名 // converter.setKeyPair(factory.getKeyPair("oauth2")); return converter; } /** * 指定令牌管理方式 * @return */ @Bean public TokenStore tokenStore() { // redis 管理令牌 // return new RedisTokenStore(redisConnectionFactory); // 注入数据源 // return new JdbcTokenStore(dataSource()); // 使用JWT管理令牌 return new JwtTokenStore(jwtAccessTokenConverter()); }6、userdetail设置
Component("customUserDetailsService") public class CustomUserDetailsService extends AbstractUserDetailsService { Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private SysUserService sysUserService; @Override SysUser findSysUser(String usernameOrMobile){ logger.info("请求认证的用户名:" + usernameOrMobile); return sysUserService.findByUsername(usernameOrMobile); }7、userdetail 父类设置
public abstract class AbstractUserDetailsService implements UserDetailsService { @Autowired private SysPermissionService sysPermissionService; /** * 每次登录都会调用这个方法验证用户信息 * @param username * @return * @throws UsernameNotFoundException */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { /** * 通过请求的用户名去数据库中查询用户信息,这里用户信息都查询出来了,密码也就获取到了。 */ SysUser sysUser = findSysUser(username); /** * 查询权限 */ findSysPermission(sysUser); return sysUser; } /** * @param usernameOrMobile 用户或手机号 * @return * @throws UsernameNotFoundException */ abstract SysUser findSysUser(String usernameOrMobile); /** * 查询认证信息 * @param sysUser * @throws UsernameNotFoundException */ public void findSysPermission(SysUser sysUser) throws UsernameNotFoundException{ if(sysUser == null) { throw new UsernameNotFoundException("未查询到有效用户信息"); } // 2. 查询该用户有哪一些权限 List<SysPermission> sysPermissions = sysPermissionService.findByUserId(sysUser.getId()); // 无权限 if(CollectionUtils.isEmpty(sysPermissions)) { return; } // 存入权限,认证通过后用于渲染左侧菜单 sysUser.setPermissions(sysPermissions); // 3. 封装用户信息和权限信息 List<GrantedAuthority> authorities = new ArrayList<>(); for(SysPermission sp: sysPermissions) { //权限标识 authorities.add(new SimpleGrantedAuthority(sp.getCode())); } sysUser.setAuthorities(authorities); }8、资源服务器配置:
@Configuration @EnableResourceServer // 标识为资源服务器,请求服务中的资源,就要带着token过来,找不到token或token是无效访问不了资源 @EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法级别权限控制 public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Autowired private TokenStore tokenStore; /** * 配置当前资源服务器的ID */ public static final String RESOURCE_ID = "product_api"; /** * 配置当前资源服务器的ID * @param resources * @throws Exception */ @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { // 当前资源服务器的资源id,认证服务会认证客户端有没有访问这个资源id的权限,有则可以访问当前服务 resources.resourceId(RESOURCE_ID) // 实现令牌服务, ResourceServerTokenServices实例 // .tokenServices(tokenService()) .tokenStore(tokenStore) ; } /** * 配置资源服务器如何验证token有效性 * 1. DefaultTokenServices * 如果认证服务器和资源服务器同一服务时,则直接采用此默认服务验证即可 * 2. RemoteTokenServices (当前采用这个) * 当认证服务器和资源服务器不是同一服务时, 要使用此服务去远程认证服务器验证 * @return */ /*public ResourceServerTokenServices tokenService(){ // 远程认证服务器进行校验 token 是否有效 RemoteTokenServices service = new RemoteTokenServices(); // 请求认证服务器校验的地址,默认情况 这个地址在认证服务器它是拒绝访问,要设置为认证通过可访问 service.setCheckTokenEndpointUrl("http://localhost:8090/auth/oauth/check_token"); // 客服端名称 service.setClientId("sse-pc"); // 客服端密码 service.setClientSecret("123456"); return service; }*/ @Override public void configure(HttpSecurity http) throws Exception { http.sessionManagement() // SpringSecurity不会使用也不会创建HttpSession实例 .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() // 授权规则配置 .antMatchers("/product/*").hasAuthority("sys:user:list") // 所有请求,都需要有all范围(scope) // .antMatchers("/**").access("#oauth2.hasScope('all')") ; }

发表评论
文章分类
联系方式
联系人: | 郑州-小万 |
---|---|
电话: | 13803993919 |
Email: | 1027060531@qq.com |
QQ: | 1027060531 |
网址: | www.wanhejia.com |
Update Required
To play the media you will need to either update your browser to a recent version or update your Flash plugin.