如何进行 Auth0 JWT token user Role-based 授权
How to perform Auth0 JWT token user Role-based authorization
我正在编写 Spring Boot REST API,并且我正在使用 JWT 令牌。现在,我正在尝试创建基于角色的授权。
这是我正在使用的tutorial/implementation。
https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/
我用额外的 Role 实体扩展了这个实现,并添加了 @ManyToMany 映射到 ApplicationUser 实体。
现在,据我了解,应该将用户角色添加到令牌(在其创建期间)。
所以,这是一个现有的代码:
@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication auth) throws IOException, ServletException {
String token = JWT.create()
.withSubject(((User) auth.getPrincipal()).getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.sign(HMAC512(SECRET.getBytes()));
res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
}
我想应该在此处添加用户角色。有一个函数:
withArrayClaim(String Name, String[] items)
这是我的第一个问题:我不确定如何正确添加它。
然后是这个片段,据我了解是验证token的地方:
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
String user = JWT.require(Algorithm.HMAC512(SECRET.getBytes()))
.build()
.verify(token.replace(TOKEN_PREFIX, ""))
.getSubject();
if (user != null) {
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
}
return null;
}
return null;
}
困扰我的是片段:
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
我不明白为什么会有 null(Inteliij 将其突出显示为 'credentials')和这个新的 ArrayList。有没有我应该从令牌中获取角色并添加它们的地方?
我知道,这是一个范围很广的问题,但我找不到其他解决方案。
或者也许有一种更简单的方法来创建简单的 JWT 令牌 authenitcation/authorization(基于角色)。
期待您的回答!
编辑:
或者也许有更简单的解决方案 i - 不将用户角色保留在键中 - 但仅将它们添加到 null 和 new ArrayList 所在的 'second' 部分?
只需创建基于用户角色的授予权限并使用它验证用户。然后经过身份验证的用户主体将包含角色。
简单示例:
UserEntity userEntity = userRepository.findUserByEmail(user); // this depends of course on your implementation
if (userEntity == null) return null;
List<RoleEntity> roles = userEntity.getRoles();
Collection<GrantedAuthority> authorities = new HashSet<>();
roles.forEach((role) -> {
authorities.add(new SimpleGrantedAuthority(role.getName()));
});
return new UsernamePasswordAuthenticationToken(user, null, authorities);
更好的是,您可以创建一个从 spring 安全性实施 UserDetails 的 UserPrincipal。
public class UserPrincipal implements UserDetails {
private static final long serialVersionUID = 1L;
private final UserEntity userEntity;
public UserPrincipal(UserEntity userEntity){
this.userEntity = userEntity;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new HashSet<>();
// Get user Roles
Collection<RoleEntity> roles = userEntity.getRoles();
if(roles == null) return authorities;
roles.forEach((role) -> {
authorities.add(new SimpleGrantedAuthority(role.getName()));
});
return authorities;
}
@Override
public String getPassword() {
return this.userEntity.getEncryptedPassword();
}
@Override
public String getUsername() {
return this.userEntity.getEmail();
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
}
并使用它:
UserEntity userEntity = userRepository.findUserByEmail(user);
if (userEntity == null) return null;
UserPrincipal userPrincipal = new UserPrincipal(userEntity);
return new UsernamePasswordAuthenticationToken(userPrincipal, null, userPrincipal.getAuthorities());
我正在编写 Spring Boot REST API,并且我正在使用 JWT 令牌。现在,我正在尝试创建基于角色的授权。
这是我正在使用的tutorial/implementation。
https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/
我用额外的 Role 实体扩展了这个实现,并添加了 @ManyToMany 映射到 ApplicationUser 实体。
现在,据我了解,应该将用户角色添加到令牌(在其创建期间)。 所以,这是一个现有的代码:
@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication auth) throws IOException, ServletException {
String token = JWT.create()
.withSubject(((User) auth.getPrincipal()).getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.sign(HMAC512(SECRET.getBytes()));
res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
}
我想应该在此处添加用户角色。有一个函数:
withArrayClaim(String Name, String[] items)
这是我的第一个问题:我不确定如何正确添加它。
然后是这个片段,据我了解是验证token的地方:
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
String user = JWT.require(Algorithm.HMAC512(SECRET.getBytes()))
.build()
.verify(token.replace(TOKEN_PREFIX, ""))
.getSubject();
if (user != null) {
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
}
return null;
}
return null;
}
困扰我的是片段:
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
我不明白为什么会有 null(Inteliij 将其突出显示为 'credentials')和这个新的 ArrayList。有没有我应该从令牌中获取角色并添加它们的地方?
我知道,这是一个范围很广的问题,但我找不到其他解决方案。 或者也许有一种更简单的方法来创建简单的 JWT 令牌 authenitcation/authorization(基于角色)。
期待您的回答!
编辑:
或者也许有更简单的解决方案 i - 不将用户角色保留在键中 - 但仅将它们添加到 null 和 new ArrayList 所在的 'second' 部分?
只需创建基于用户角色的授予权限并使用它验证用户。然后经过身份验证的用户主体将包含角色。 简单示例:
UserEntity userEntity = userRepository.findUserByEmail(user); // this depends of course on your implementation
if (userEntity == null) return null;
List<RoleEntity> roles = userEntity.getRoles();
Collection<GrantedAuthority> authorities = new HashSet<>();
roles.forEach((role) -> {
authorities.add(new SimpleGrantedAuthority(role.getName()));
});
return new UsernamePasswordAuthenticationToken(user, null, authorities);
更好的是,您可以创建一个从 spring 安全性实施 UserDetails 的 UserPrincipal。
public class UserPrincipal implements UserDetails {
private static final long serialVersionUID = 1L;
private final UserEntity userEntity;
public UserPrincipal(UserEntity userEntity){
this.userEntity = userEntity;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new HashSet<>();
// Get user Roles
Collection<RoleEntity> roles = userEntity.getRoles();
if(roles == null) return authorities;
roles.forEach((role) -> {
authorities.add(new SimpleGrantedAuthority(role.getName()));
});
return authorities;
}
@Override
public String getPassword() {
return this.userEntity.getEncryptedPassword();
}
@Override
public String getUsername() {
return this.userEntity.getEmail();
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
}
并使用它:
UserEntity userEntity = userRepository.findUserByEmail(user);
if (userEntity == null) return null;
UserPrincipal userPrincipal = new UserPrincipal(userEntity);
return new UsernamePasswordAuthenticationToken(userPrincipal, null, userPrincipal.getAuthorities());