提交 578dba07 编写于 作者: zlt2000's avatar zlt2000

增强jwtToken额外添加用户id参数,@LoginUser注解能获取(id、username和roles)三个属性

上级 c88369dd
package com.central.oauth2.common.converter;
import com.central.common.model.SysUser;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 优化自org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter
* jwt返回的principal改为返回SysUser,增加扩展字段
*
* @author zlt
* @date 2019/8/5
*/
public class CustomUserAuthenticationConverter implements UserAuthenticationConverter {
private Collection<? extends GrantedAuthority> defaultAuthorities;
private UserDetailsService userDetailsService;
/**
* Optional {@link UserDetailsService} to use when extracting an {@link Authentication} from the incoming map.
*
* @param userDetailsService the userDetailsService to set
*/
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
/**
* Default value for authorities if an Authentication is being created and the input has no data for authorities.
* Note that unless this property is set, the default Authentication created by {@link #extractAuthentication(Map)}
* will be unauthenticated.
*
* @param defaultAuthorities the defaultAuthorities to set. Default null.
*/
public void setDefaultAuthorities(String[] defaultAuthorities) {
this.defaultAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils
.arrayToCommaDelimitedString(defaultAuthorities));
}
@Override
public Map<String, ?> convertUserAuthentication(Authentication authentication) {
Map<String, Object> response = new LinkedHashMap<String, Object>();
response.put(USERNAME, authentication.getName());
if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
response.put(AUTHORITIES, AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
}
return response;
}
@Override
public Authentication extractAuthentication(Map<String, ?> map) {
if (map.containsKey(USERNAME)) {
Object principal = map.get(USERNAME);
Collection<? extends GrantedAuthority> authorities = getAuthorities(map);
if (userDetailsService != null) {
UserDetails user = userDetailsService.loadUserByUsername((String) map.get(USERNAME));
authorities = user.getAuthorities();
principal = user;
} else {
Integer id = (Integer)map.get("id");
SysUser user = new SysUser();
user.setUsername((String)principal);
user.setId(Long.valueOf(id));
principal = user;
}
return new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);
}
return null;
}
private Collection<? extends GrantedAuthority> getAuthorities(Map<String, ?> map) {
if (!map.containsKey(AUTHORITIES)) {
return defaultAuthorities;
}
Object authorities = map.get(AUTHORITIES);
if (authorities instanceof String) {
return AuthorityUtils.commaSeparatedStringToAuthorityList((String) authorities);
}
if (authorities instanceof Collection) {
return AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils
.collectionToCommaDelimitedString((Collection<?>) authorities));
}
throw new IllegalArgumentException("Authorities must be either a String or a Collection");
}
}
package com.central.oauth2.common.store;
import com.central.common.model.SysUser;
import com.central.oauth2.common.converter.CustomUserAuthenticationConverter;
import org.springframework.cloud.bootstrap.encrypt.KeyProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
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;
......@@ -9,6 +14,8 @@ import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFacto
import javax.annotation.Resource;
import java.security.KeyPair;
import java.util.HashMap;
import java.util.Map;
/**
* 认证服务器使用 JWT RSA 非对称加密令牌
......@@ -38,6 +45,8 @@ public class AuthJwtTokenStore {
(keyProperties.getKeyStore().getLocation(), keyProperties.getKeyStore().getSecret().toCharArray())
.getKeyPair(keyProperties.getKeyStore().getAlias());
converter.setKeyPair(keyPair);
DefaultAccessTokenConverter tokenConverter = (DefaultAccessTokenConverter)converter.getAccessTokenConverter();
tokenConverter.setUserTokenConverter(new CustomUserAuthenticationConverter());
return converter;
}
......@@ -47,12 +56,18 @@ public class AuthJwtTokenStore {
*
* @return TokenEnhancer
*/
/*@Bean
@Bean
public TokenEnhancer tokenEnhancer() {
return (accessToken, authentication) -> {
final Map<String, Object> additionalInfo = new HashMap<>(1);
Object principal = authentication.getPrincipal();
//增加id参数
if (principal instanceof SysUser) {
SysUser user = (SysUser)principal;
additionalInfo.put("id", user.getId());
}
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
};
}*/
}
}
......@@ -2,6 +2,7 @@ package com.central.oauth2.common.store;
import cn.hutool.core.util.StrUtil;
import com.central.common.constant.SecurityConstants;
import com.central.oauth2.common.converter.CustomUserAuthenticationConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
import org.springframework.context.annotation.Bean;
......@@ -10,6 +11,7 @@ import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
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;
......@@ -41,6 +43,8 @@ public class ResJwtTokenStore {
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setVerifierKey(getPubKey());
DefaultAccessTokenConverter tokenConverter = (DefaultAccessTokenConverter)converter.getAccessTokenConverter();
tokenConverter.setUserTokenConverter(new CustomUserAuthenticationConverter());
return converter;
}
......
......@@ -16,6 +16,11 @@ public interface SecurityConstants {
*/
String USER_HEADER = "x-user-header";
/**
* 用户id信息头
*/
String USER_ID_HEADER = "x-userId-header";
/**
* 角色信息头
*/
......
......@@ -58,6 +58,7 @@ public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
LoginUser loginUser = methodParameter.getParameterAnnotation(LoginUser.class);
boolean isFull = loginUser.isFull();
HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
String userId = request.getHeader(SecurityConstants.USER_ID_HEADER);
String username = request.getHeader(SecurityConstants.USER_HEADER);
String roles = request.getHeader(SecurityConstants.ROLE_HEADER);
if (StrUtil.isBlank(username)) {
......@@ -69,6 +70,7 @@ public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
user = userService.selectByUsername(username);
} else {
user = new SysUser();
user.setId(Long.valueOf(userId));
user.setUsername(username);
}
List<SysRole> sysRoleList = new ArrayList<>();
......
......@@ -2,6 +2,7 @@ package com.central.gateway.filter.pre;
import cn.hutool.core.collection.CollectionUtil;
import com.central.common.constant.SecurityConstants;
import com.central.common.model.SysUser;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
......@@ -40,12 +41,15 @@ public class UserInfoHeaderFilter extends ZuulFilter {
public Object run() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && !(authentication instanceof AnonymousAuthenticationToken)) {
String username = authentication.getName();
SysUser user = (SysUser)authentication.getPrincipal();
Long userId = user.getId();
String username = user.getUsername();
OAuth2Authentication oauth2Authentication = (OAuth2Authentication)authentication;
String clientId = oauth2Authentication.getOAuth2Request().getClientId();
RequestContext ctx = RequestContext.getCurrentContext();
ctx.addZuulRequestHeader(SecurityConstants.USER_ID_HEADER, String.valueOf(userId));
ctx.addZuulRequestHeader(SecurityConstants.USER_HEADER, username);
ctx.addZuulRequestHeader(SecurityConstants.CLIENT_HEADER, clientId);
ctx.addZuulRequestHeader(SecurityConstants.ROLE_HEADER, CollectionUtil.join(authentication.getAuthorities(), ","));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册