无法实现对 Spring-Boot API 的基于角色的访问
Unable to implement Role based access to Spring-Boot API
我是 Spring-Boot.I 的新手,想创建一个 API,它将具有基于角色的访问权限和基于 JWT 令牌的身份验证。但是,无法实现。
我没有使用 JPA 和 Hibernate 来获取和映射数据。相反,我使用 Ibatis.I 尝试过 @PreAuthorize 和 antMatchers & hasRole,但失败了。通过从 JWT 令牌获取用户 ID,我正在获取详细信息和角色并将它们设置为 SecurityContextHolder.getContext().setAuthentication,但仍然无法正常工作。
安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.authorizeRequests()
.anyRequest().authenticated()
.antMatchers("api/management/reports").hasRole("Supervisor");
}
控制器
@RestController
@RequestMapping("api")
@CrossOrigin
public class MyController {
@PreAuthorize("hasRole('Supervisor')")
@GetMapping("username")
public String reports(){
SecurityContext securityContext = SecurityContextHolder.getContext();
return securityContext.getAuthentication().getName();
}
}
授权过滤器
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
public JwtAuthorizationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String header = request.getHeader(JwtProperties.HEADER_STRING);
if (header == null || !header.startsWith(JwtProperties.TOKEN_PREFIX)) {
chain.doFilter(request, response);
return;
}
Authentication authentication = getUsernamePasswordAuthentication(request,header);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}
private Authentication getUsernamePasswordAuthentication(HttpServletRequest request, String header) {
try {
String token = header.replace(JwtProperties.TOKEN_PREFIX,"");
String userName = JWT.require(HMAC512(JwtProperties.SECRET.getBytes()))
.build()
.verify(token)
.getSubject();
List<User> searchedUserList = getUserDetailsDAO().getUserDetails(userName);
if (null !=searchedUserList && searchedUserList.size()>0) {
User searchedUser = new User();
searchedUser = searchedUserList.get(0);
List<RoleAccess> roleAccessList = new ArrayList<RoleAccess>();
XrefUsrRole oXrefUsrRole = new XrefUsrRole();
oXrefUsrRole.setUserName(searchedUser.getUsername());
roleAccessList = getRoleAccessDAO().getAccessDetails(oXrefUsrRole);
List<GrantedAuthority> authorities = uildUserAuthority(roleAccessList);
org.springframework.security.core.userdetails.User newUser = buildUserForAuthentication(searchedUser, authorities);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(newUser, null,authorities);
return auth;
}
return null;
}
return null;
} catch (IOException e) {
return null;
}
private org.springframework.security.core.userdetails.User buildUserForAuthentication(User searchedUser, List<GrantedAuthority> authorities) {
return new org.springframework.security.core.userdetails.User(searchedUser.getUsername(), searchedUser.getPassword(), true, true, true, true, authorities);
}
private List<GrantedAuthority> buildUserAuthority(List<RoleAccess> roleAccessList) {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
// Build user's authorities
for (RoleAccess userRole : roleAccessList) {
setAuths.add(new SimpleGrantedAuthority("ROLE_"+userRole.getModifiedBy()));
}
List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);
return Result;
}
在这种情况下,api/username 应该无法访问,除非用户具有 主管 角色。
您有 ROLE_"+userRole.getModifiedBy()) 这意味着您正在授予 ROLE_NAME 角色在 PreAuthorize 中,您有导致问题的主管。您可以将角色存储为 ROLE_SUPERVISOR 在数据库中,然后按以下方式使用它
// Build user's authorities
for (RoleAccess userRole : roleAccessList) {
setAuths.add(new SimpleGrantedAuthority("ROLE_"+userRole.getModifiedBy()));
}
使用
@PreAuthorize("hasRole('ROLE_SUPERVISOR')")
.antMatchers("api/management/reports").hasRole("SUPERVISOR");
我是 Spring-Boot.I 的新手,想创建一个 API,它将具有基于角色的访问权限和基于 JWT 令牌的身份验证。但是,无法实现。
我没有使用 JPA 和 Hibernate 来获取和映射数据。相反,我使用 Ibatis.I 尝试过 @PreAuthorize 和 antMatchers & hasRole,但失败了。通过从 JWT 令牌获取用户 ID,我正在获取详细信息和角色并将它们设置为 SecurityContextHolder.getContext().setAuthentication,但仍然无法正常工作。
安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.authorizeRequests()
.anyRequest().authenticated()
.antMatchers("api/management/reports").hasRole("Supervisor");
}
控制器
@RestController
@RequestMapping("api")
@CrossOrigin
public class MyController {
@PreAuthorize("hasRole('Supervisor')")
@GetMapping("username")
public String reports(){
SecurityContext securityContext = SecurityContextHolder.getContext();
return securityContext.getAuthentication().getName();
}
}
授权过滤器
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
public JwtAuthorizationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String header = request.getHeader(JwtProperties.HEADER_STRING);
if (header == null || !header.startsWith(JwtProperties.TOKEN_PREFIX)) {
chain.doFilter(request, response);
return;
}
Authentication authentication = getUsernamePasswordAuthentication(request,header);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}
private Authentication getUsernamePasswordAuthentication(HttpServletRequest request, String header) {
try {
String token = header.replace(JwtProperties.TOKEN_PREFIX,"");
String userName = JWT.require(HMAC512(JwtProperties.SECRET.getBytes()))
.build()
.verify(token)
.getSubject();
List<User> searchedUserList = getUserDetailsDAO().getUserDetails(userName);
if (null !=searchedUserList && searchedUserList.size()>0) {
User searchedUser = new User();
searchedUser = searchedUserList.get(0);
List<RoleAccess> roleAccessList = new ArrayList<RoleAccess>();
XrefUsrRole oXrefUsrRole = new XrefUsrRole();
oXrefUsrRole.setUserName(searchedUser.getUsername());
roleAccessList = getRoleAccessDAO().getAccessDetails(oXrefUsrRole);
List<GrantedAuthority> authorities = uildUserAuthority(roleAccessList);
org.springframework.security.core.userdetails.User newUser = buildUserForAuthentication(searchedUser, authorities);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(newUser, null,authorities);
return auth;
}
return null;
}
return null;
} catch (IOException e) {
return null;
}
private org.springframework.security.core.userdetails.User buildUserForAuthentication(User searchedUser, List<GrantedAuthority> authorities) {
return new org.springframework.security.core.userdetails.User(searchedUser.getUsername(), searchedUser.getPassword(), true, true, true, true, authorities);
}
private List<GrantedAuthority> buildUserAuthority(List<RoleAccess> roleAccessList) {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
// Build user's authorities
for (RoleAccess userRole : roleAccessList) {
setAuths.add(new SimpleGrantedAuthority("ROLE_"+userRole.getModifiedBy()));
}
List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);
return Result;
}
在这种情况下,api/username 应该无法访问,除非用户具有 主管 角色。
您有 ROLE_"+userRole.getModifiedBy()) 这意味着您正在授予 ROLE_NAME 角色在 PreAuthorize 中,您有导致问题的主管。您可以将角色存储为 ROLE_SUPERVISOR 在数据库中,然后按以下方式使用它
// Build user's authorities
for (RoleAccess userRole : roleAccessList) {
setAuths.add(new SimpleGrantedAuthority("ROLE_"+userRole.getModifiedBy()));
}
使用
@PreAuthorize("hasRole('ROLE_SUPERVISOR')")
.antMatchers("api/management/reports").hasRole("SUPERVISOR");