【问题标题】:Oauth2 get Username from tokenOauth2 从令牌中获取用户名
【发布时间】:2019-12-27 21:35:25
【问题描述】:

我已经将 Ouath2 实现为我的 Spring 引导休息控制器的安全性。 在调用我的任何资源之前,oauth2 会验证用户表中用户的令牌。我的问题是如何避免 user1 令牌在请求中并且请求正文包含 user2 修改的数据的情况?我需要检查一下,这样带有他的令牌的 User1 应该只能为他自己修改数据。如果 user1 和他的 toekn 在请求正文中有 user2 数据应该抛出 403。

我在想是否可以从服务层的令牌中获取用户名来进行此检查?任何帮助表示赞赏

【问题讨论】:

    标签: spring rest spring-boot oauth-2.0 spring-security-oauth2


    【解决方案1】:

    您正在使用 Spring Security 进行身份验证。

    您可以从 SecurityContext 获取用户详细信息

    Authentication authentication = SecurityContextHolder.getContext()
        .getAuthentication();
    
    UserDetails userDetail = authentication.getPrincipal();
    userDetail.getUsername();
    

    或在休息控制器中

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    public String currentUserName(Principal principal) {
        return principal.getName();
    }
    

    或

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    public String currentUserName(HttpServletRequest request) {
        Principal principal = request.getUserPrincipal();
    
        return principal.getName();
    }
    

    【讨论】:

    • @RequestMapping(value = "/username", method = RequestMethod.GET) public String currentUserName(Principal principal) { return principal.getName(); } 我得到 null 的主体
    • 您好!有进口吗?
    【解决方案2】:

    您可以通过创建自定义验证来做到这一点。

    import javax.validation.Constraint;
    import javax.validation.Payload;
    import java.lang.annotation.*;
    
    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Constraint(validatedBy = {OwnUserValidator.class})
    public @interface OwnUser {
    String message() default Messages.INVALID_WALLET;
    
    Class<?>[] groups() default {};
    
    Class<? extends Payload>[] payload() default {};
    }
    

    //

    import org.springframework.beans.factory.annotation.Autowired;
    
    import javax.validation.ConstraintValidator;
    import javax.validation.ConstraintValidatorContext;
    
    public class OwnUserValidator implements ConstraintValidator<OwnUser, String> {
    
    @Override
    public void initialize(OwnUser constraintAnnotation) {
    
    }
    
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        String tokenName = THREAD_LOCAL_TOKEN.get();
        if(tokenName.equalsIgnoreCase(value)){
        return true;
        }
        return false;
    }
    }
    

    然后在请求正文中的用户字段之前使用此 @OwnUser 注释

    public class Request implements Serializable{
    
    private static final long serialVersionUID = 1L; 
    
    @OwnUser
    private String user;
    }
    

    当请求在这里调用doFilterInternal方法时,你将令牌保存在threadLocal中:

    public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    
    public static ThreadLocal<String> THREAD_LOCAL_TOKEN = new ThreadLocal<>();
    
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
    
        //get token from httpServlet request.
        THREAD_LOCAL_TOKEN.set(nameFromtoken);
        //ur neccessary code
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-09
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多