当前位置: 首页 > 知识库问答 >
问题:

Spring Boot如何使用jwt进行用户角色管理

华君浩
2023-03-14

我正在用spring boot写一个RESTful api。我用的是spring boot,jersey,mongo db,swagger,spring boot security和jwt。

我已经为DB的请求编写了模型和存储库。现在我已经集成了Security和jwt令牌。

现在我需要离散用户的角色,因为用户无法调用需要管理员权限的路由。

我有一条登录路线,它返回一个令牌。这是我的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,当用户登录时,它返回令牌给我

...
@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;
}
...

我想在方法上的endpoint类上插入这个

@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();
    }
....

我如何建立一种机制来分配给用户角色,以及我如何在令牌中传递角色并在路由上离散化用户角色?

共有3个答案

勾渝
2023-03-14

您应该将角色添加到令牌中,例如,您可以参考以下链接:-http://www.svlada.com/jwt-token-authentication-with-spring-boot/

融伯寅
2023-03-14

首先需要在JWT中添加角色。为此,您可以在JWT生成器类中添加为声明。

    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        Set<String> Userroles = new HashSet<>();
        User user = userRepository.findByUsername(userDetails.getUsername());
        for(Role role:user.getRoles()){
            Userroles.add(role.getName());
        }
        claims.put("Roles",Userroles.toArray());
        return createToken(claims, userDetails.getUsername());
    }

    private String createToken(Map<String, Object> claims, String subject) {
        
        return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
    }

在用户模型类中需要包括角色集或任何其他数据结构。

 @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "USER_ROLES", joinColumns = {
            @JoinColumn(name = "USER_ID") }, inverseJoinColumns = {
            @JoinColumn(name = "ROLE_ID") })
    private Set<Role> roles;

在存储库中需要有一个像下面这样的方法。

User findByUsername(String username);

请检查此Github Repo(https://github.com/Senthuran100/SpringBoot_JWT)供您参考。

步联
2023-03-14

您需要将用户角色作为附加声明存储在JWT令牌中,在令牌验证后提取它们,并作为主体的“权限”传递:

 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);
 类似资料:
  • 6.0 版本开始,管理员可以在用户管理界面为一个用户赋予一个角色,不同角色可以配置不同权限,目前支持 10 种权限。 6.1 版本开始,我们添加了一个新的权限 relo_quota(角色配额),该权限用来给某个用户的角色设置空间配额。例如,我们可以通过添加 'role_quota': '100g' 为 employee 角色设置100GB的空间配额,同时其他用户还是使用默认的空间配额。 Seafi

  • 主要内容:一、用户管理,二、权限管理,三、权限表,四、角色管理一、用户管理 1.创建用户 用户名参数表示新建用户的账户,由用户(User) 和主机名(Host) 构成,默认host为'%',表示所有主机(ip)都可登录,也可以使用如'lxc'@'192.168.%.%'的形式 可以不指定用户密码,无需密码登录; 2.查看用户 3.修改用户 4.删除用户 1.使用DROP USER语句来删除用户时,必须用于DROP USER权限。DROP USER语句的基本语

  • 我目前试图设置一个管理员角色,以便访问一个简单的管理页面,使用以下留档通过提供:连接角色 我已经有一段时间不停地用我的头来撞击它,但我仍然不知道如何设置角色,例如,现在我正在从数据库中提取一个管理值,并暂时将其存储在一个全局变量中,但我不知道如何将其用于连接角色,比如只允许特定用户访问我的管理页面。 如果我的文档没有帮助我确保仅当用户是管理员时才能访问网页,那么有人可以澄清或展示如何执行此操作的示

  • 您好,我正在使用平均堆栈和jwt登录,我想限制一些数据只有userRole'admin'这是我的user.js 这就是我验证jwt令牌的方法 这是我希望使用verifyToken函数仅为'admin'角色限制的数据 我的问题是,我如何访问当前登录的用户信息,并仅使管理员可读的/特殊的

  • 我不太确定如何使用actors访问数据库。在Akka的文档和书籍中,这个主题似乎被省略了。 一种解决方案可以是无状态参与者中的包装DAO。例如,对于数据库中的每个表(或域对象类型或聚合类型),可以创建一个负责所有CRUD操作的参与者。这种方法的一个变体可以是命令和查询的分离。例如,对于每个数据类型,1个命令参与者(用于并发)和10个查询参与者(用于并行性)。 另一种方法可以是创建只表示数据库中一行

  • 我不知道我需要在我的客户的谷歌云平台上有哪个角色/S,以执行以下操作:-连接并管理Firestore数据库到他们的Firebase应用程序。-从外部应用程序使用Google Cloud Firestore API。 有这么多角色...有人帮忙吗?:)我已经有了Firebase Analytics Admin,但当我试图通过Firebase访问Firestore时,我得到的消息是“要管理云Fires