问题描述
我正在用 spring boot 编写一个 RESTful api.我正在使用 spring boot、jersey、mongo db、swagger、spring boot security 和 jwt.
I'm writing a RESTful api with spring boot. I'm using spring boot, jersey, mongo db, swagger, spring boot security and jwt.
我已经编写了模型、数据库请求的存储库.现在我已经集成了 Security 和 jwt 令牌.
I have written the models, the repositories for the requests to the DB. Now I have integrated the Security and jwt token.
现在我需要离散化用户的角色,因为用户无法调用需要管理员权限的路由.
Now I need to discretize the role of the users, because a user cant call a route that need an admin priviledges.
我有一个登录路径,它返回一个令牌.这是我的 SecurityConfig 的代码
I have a route for login, it's return a token. This is the code of my SecurityConfig
...
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
UserRepository userRepository;
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/api/swagger.json").permitAll()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.antMatchers("/api/*").authenticated()
.and()
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager(), userRepository),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
}
我编写了 JWTLoginFilter,当用户登录时返回我的令牌
I written the JWTLoginFilter that return me the token when user makes login
...
@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException, IOException, ServletException {
Credential creds = new ObjectMapper().readValue(req.getInputStream(), Credential.class);
User user = userRepository.login(creds);
if (user == null)
throw new BadCredentialsException("");
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
creds.getUsername(),
creds.getPassword()
);
return token;
}
...
我想在方法的端点类中插入它
I want insert this on my endpoint class on method
@PreAuthorize("hasRole('ROLE_ADMIN')")
这是端点的一部分
....
@Component
@Path("story")
@Api(value = "Story", produces = "application/json")
public class StoryEndpoint {
private static final Logger LOGGER = LoggerFactory.getLogger(StoryEndpoint.class);
@Autowired
StoryRepository storyRepository;
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@PreAuthorize("hasRole('ROLE_ADMIN')") <--- I want insert here
@ApiOperation(value = "Get All Story", response = Story.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "hello resource found"),
@ApiResponse(code = 404, message = "Given admin user not found")
})
public Response getAllStory(){
Iterable<Story> stories = storyRepository.findAll();
LOGGER.info("getAllStory");
return (stories!=null) ? Response.ok(stories).build() : Response.ok(ResponseErrorGenerator.generate(Response.Status.NOT_FOUND)).status(Response.Status.NOT_FOUND).build();
}
....
如何制定一种机制来为用户分配角色,以及如何在令牌中传递角色并离散化路由用户角色?
How I can make a mechanism for assign to user the role and how i can pass the role in token and discretize on route the role of user?
推荐答案
您需要将用户角色作为附加声明存储在 JWT 令牌中,在令牌验证后提取它们并作为主体的权限"传递:
You need to store user roles inside JWT token as additional claims, extract them after token validation and pass as 'authorities' for principal:
Collection<? extends GrantedAuthority> authorities
= Arrays.asList(claims.get(AUTHORITIES_KEY).toString().split(",")).stream()
.map(authority -> new SimpleGrantedAuthority(authority))
.collect(Collectors.toList());
User principal = new User(claims.getSubject(), "",
authorities);
UsernamePasswordAuthenticationToken t
= new UsernamePasswordAuthenticationToken(principal, "", authorities);
这篇关于Spring Boot 如何使用 jwt 管理用户角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!