Skip to content

Commit

Permalink
集成权限框架
Browse files Browse the repository at this point in the history
  • Loading branch information
fangp committed May 3, 2018
1 parent da4fbec commit ba76905
Show file tree
Hide file tree
Showing 44 changed files with 12,972 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;


/**
* RedisSerializer编码解码类
*/
public class RedisObjectSerializer implements RedisSerializer {

static final byte[] EMPTY_ARRAY = new byte[0];
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.peng.auth.api.pojo.auth;

import com.peng.main.api.mapper.model.BaseUser;
import org.springframework.security.core.CredentialsContainer;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.*;

/**
* Created by fp295 on 2018/4/29.
* 包装org.springframework.security.core.userdetails.User类
*/
public class BaseUserDetail implements UserDetails, CredentialsContainer {

private final BaseUser baseUser;
private final org.springframework.security.core.userdetails.User user;

public BaseUserDetail(BaseUser baseUser, User user) {
this.baseUser = baseUser;
this.user = user;
}


@Override
public void eraseCredentials() {
user.eraseCredentials();
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getAuthorities();
}

@Override
public String getPassword() {
return user.getPassword();
}

@Override
public String getUsername() {
return user.getUsername();
}

@Override
public boolean isAccountNonExpired() {
return user.isAccountNonExpired();
}

@Override
public boolean isAccountNonLocked() {
return user.isAccountNonLocked();
}

@Override
public boolean isCredentialsNonExpired() {
return user.isCredentialsNonExpired();
}

@Override
public boolean isEnabled() {
return user.isEnabled();
}

public BaseUser getBaseUser() {
return baseUser;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.peng.auth.api.token;

import com.peng.auth.api.pojo.Constant;
import com.peng.auth.api.pojo.auth.BaseGrantedAuthority;
import com.peng.auth.api.pojo.auth.BaseUserDetail;
import com.peng.common.utils.JsonUtils;
import com.peng.main.api.mapper.model.BaseUser;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
Expand All @@ -12,22 +12,35 @@

/**
* Created by fp295 on 2018/4/16.
* 自定义JwtAccessToken转换器
*/
public class JwtAccessToken extends JwtAccessTokenConverter {

/**
* 生成token
* @param accessToken
* @param authentication
* @return
*/
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
DefaultOAuth2AccessToken defaultOAuth2AccessToken = new DefaultOAuth2AccessToken(accessToken);

// 设置用户信息
BaseGrantedAuthority baseGrantedAuthority = (BaseGrantedAuthority)authentication.getAuthorities().toArray()[0];
BaseUser baseUser = baseGrantedAuthority.getBaseUser();
// 设置额外用户信息
BaseUser baseUser = ((BaseUserDetail) authentication.getPrincipal()).getBaseUser();
baseUser.setPassword(null);
// 将用户信息添加到token额外信息中
defaultOAuth2AccessToken.getAdditionalInformation().put(Constant.USER_INFO, baseUser);

return super.enhance(defaultOAuth2AccessToken, authentication);
}

/**
* 解析token
* @param value
* @param map
* @return
*/
@Override
public OAuth2AccessToken extractAccessToken(String value, Map<String, ?> map){
OAuth2AccessToken oauth2AccessToken = super.extractAccessToken(value, map);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.peng.auth.provider.config.auth;


import com.peng.auth.api.token.JwtAccessToken;
import com.peng.auth.provider.service.BaseUserDetailService;

import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -53,46 +54,46 @@ public JdbcTokenStore getJdbcTokenStore() {

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(getJdbcClientDetails());
// 使用JdbcClientDetailsService客户端详情服务
clients.withClientDetails(new JdbcClientDetailsService(dataSource));
}


@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.authenticationManager(authenticationManager)
// 配置JwtAccessToken转换器
.accessTokenConverter(jwtAccessTokenConverter())
.reuseRefreshTokens(false);
// refresh_token需要userDetailsService
.reuseRefreshTokens(false).userDetailsService(userDetailsService);
//.tokenStore(getJdbcTokenStore());
}

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess(
"isAuthenticated()");
oauthServer
// 开启/oauth/token_key验证端口无权限访问
.tokenKeyAccess("permitAll()")
// 开启/oauth/check_token验证端口认证权限访问
.checkTokenAccess("isAuthenticated()");
}

/**
* key
* 使用非对称加密算法来对Token进行签名
* @return
*/
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {

final JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
final JwtAccessTokenConverter converter = new JwtAccessToken();
// 导入证书
KeyStoreKeyFactory keyStoreKeyFactory =
new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), "foobar".toCharArray());
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("test"));

return converter;
}

/**
* 客户端
*/
@Bean
public JdbcClientDetailsService getJdbcClientDetails()

{
return new JdbcClientDetailsService(dataSource);
}

/**
* 跨域
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,19 @@
@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

// 自动注入UserDetailsService
@Autowired
private BaseUserDetailService baseUserDetailService;

@Override
public void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/login").permitAll()
http // 配置登陆页/login并允许访问
.formLogin().permitAll()
// 登出页
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/")
// 其余所有请求全部需要鉴权认证
.and().authorizeRequests().anyRequest().authenticated()
// 由于使用的是JWT,我们这里不需要csrf
.and().csrf().disable();
}

Expand All @@ -44,11 +49,12 @@ public void configure(AuthenticationManagerBuilder auth) {
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider(){
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
// 设置userDetailsService
provider.setUserDetailsService(baseUserDetailService);
// 禁止隐藏用户未找到异常
provider.setHideUserNotFoundExceptions(false);
// 使用BCrypt进行密码的hash
provider.setPasswordEncoder(new BCryptPasswordEncoder(6));
return provider;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

/**
* Created by fp295 on 2018/4/12.
* Redis配置类
*/
@Configuration
public class RedisAuthConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter {

@Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/login").setViewName("login");
//registry.addViewController("/login").setViewName("login");
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.peng.auth.provider.service;

import com.peng.auth.api.pojo.auth.BaseGrantedAuthority;
import com.peng.auth.api.pojo.auth.BaseUserDetail;
import com.peng.common.pojo.ResponseData;
import com.peng.main.api.mapper.model.BaseModuleResources;
import com.peng.main.api.mapper.model.BaseRole;
Expand All @@ -14,6 +14,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
Expand Down Expand Up @@ -45,27 +46,28 @@ public class BaseUserDetailService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

// 调用FeignClient查询用户
ResponseData<BaseUser> baseUserResponseData = baseUserService.getUserByUserName(username);
if(baseUserResponseData.getData() == null || !ResponseCode.SUCCESS.getCode().equals(baseUserResponseData.getCode())){
logger.error("找不到该用户,用户名:" + username);
throw new UsernameNotFoundException("找不到该用户,用户名:" + username);
}
BaseUser baseUser = baseUserResponseData.getData();

//查询角色
// 调用FeignClient查询角色
ResponseData<List<BaseRole>> baseRoleListResponseData = baseRoleService.getRoleByUserId(baseUser.getId());
List<BaseRole> roles;
if(baseRoleListResponseData.getData() == null || baseRoleListResponseData.getCode() != ResponseCode.SUCCESS.getCode()){
if(baseRoleListResponseData.getData() == null || !ResponseCode.SUCCESS.getCode().equals(baseRoleListResponseData.getCode())){
logger.error("查询角色失败!");
roles = new ArrayList<>();
}else {
roles = baseRoleListResponseData.getData();
}

//查询菜单
//调用FeignClient查询菜单
ResponseData<List<BaseModuleResources>> baseModuleResourceListResponseData = baseModuleResourceService.getMenusByUserId(baseUser.getId());

// 转换权限数据
// 获取用户权限列表
List<GrantedAuthority> authorities = convertToAuthorities(baseUser, roles);

// 存储菜单到redis
Expand All @@ -76,8 +78,10 @@ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundEx
});
}

return new org.springframework.security.core.userdetails.User(baseUser.getUserName(),
// 返回带有用户权限信息的User
org.springframework.security.core.userdetails.User user = new org.springframework.security.core.userdetails.User(baseUser.getUserName(),
baseUser.getPassword(), isActive(baseUser.getActive()), true, true, true, authorities);
return new BaseUserDetail(baseUser, user);
}

private boolean isActive(int active){
Expand All @@ -89,7 +93,8 @@ private List<GrantedAuthority> convertToAuthorities(BaseUser baseUser, List<Base
// 清除 Redis 中用户的角色
redisTemplate.delete(baseUser.getId());
roles.forEach(e -> {
GrantedAuthority authority = new BaseGrantedAuthority(baseUser, e);
// 存储用户、角色信息到GrantedAuthority,并放到GrantedAuthority列表
GrantedAuthority authority = new SimpleGrantedAuthority(e.getRoleCode());
authorities.add(authority);
//存储角色到redis
redisTemplate.opsForList().rightPush(baseUser.getId(), e);
Expand Down
Loading

0 comments on commit ba76905

Please sign in to comment.