为了账号安全,请及时绑定邮箱和手机立即绑定

Java 中基于角色的静谧端点的身份验证

Java 中基于角色的静谧端点的身份验证

繁花如伊 2022-09-22 19:53:21

我正在尝试实现某种基于角色的身份验证。我正在使用 JWT 令牌。我一直在看指南,但都提到了“弹簧靴”的使用。如何在 Java 中对我的宁静端点设置基于角色的身份验证?最好通过某种过滤器。


我正在寻找一种简单地添加的方法:在端点之前。@Role(Role.ADMIN)


我已经设置了以下类:


枚举角色:


public enum Role {

    User,

    Admin

}

简单的智威汤逊令牌:


{

 "sub": "users/TzMUocMF4p",

 "exp": 1554646441,

 "username": "username@gmail.com",

 "ID": 6,

 "Role": "Admin",

 "iat": 1554641041

}

简单 CRUD 端点


@Path("User")

public class UserResource {


   @EJB

   private UserDAO userappDAO;



   @GET

   @JWTTokenNeeded

   @Produces("application/json")

   public List<Userapp> all() {

       return userappDAO.getAll();

   }

}

JWT 验证 () 类如下:@JWTTokenNeeded


@javax.ws.rs.NameBinding

@Retention(RUNTIME)

@Target({TYPE, METHOD})

public @interface JWTTokenNeeded {

}

实际过滤器:


@Provider

@JWTTokenNeeded

@Priority(Priorities.AUTHENTICATION)

public class JWTTokenNeededFilter implements ContainerRequestFilter {



    @Override

    public void filter(ContainerRequestContext requestContext) throws IOException {


// Get the HTTP Authorization header from the request

String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);


try {

    // Extract the token from the HTTP Authorization header

    String token = authorizationHeader.substring("Bearer".length()).trim();

    // Validate the token

    Jwts.parser().setSigningKey("MYSECRET".getBytes("UTF-8")).parseClaimsJws(token);


}

catch (Exception e) {

    requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());

}

}

}

如果用户未获得授权,我想通过以下方式退出:requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());


如果用户已获得授权,则端点必须执行该操作。


查看完整描述

1 回答

?
米琪卡哇伊

TA贡献1659条经验 获得超7个赞

我找到了一个可行的解决方案。它包括向接口和类添加几行。@JWTTokenNeededJWTTokenNeededFilter


我最终得到了以下代码:


JWTTokenNeedFilter:


@Provider

@JWTTokenNeeded

@Priority(Priorities.AUTHENTICATION)

public class JWTTokenNeededFilter implements ContainerRequestFilter {

    @Context

    private ResourceInfo resourceInfo;


    @Override

    public void filter(ContainerRequestContext requestContext) throws IOException {


        // Get the HTTP Authorization header from the request

        String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);


        try {

            // Extract the token from the HTTP Authorization header

            String token = authorizationHeader.substring("Bearer".length()).trim();

            // Validate the token

            Claims claims =  Jwts.parser().setSigningKey("MYSECRET".getBytes("UTF-8")).parseClaimsJws(token).getBody();


            Method method =resourceInfo.getResourceMethod();

            if( method != null){

                // Get allowed permission on method

                JWTTokenNeeded JWTContext = method.getAnnotation(JWTTokenNeeded.class);

                Role permission =  JWTContext.Permissions();


                if(permission != Role.NoRights ) {

                    // Get Role from jwt

                    String roles = claims.get("Role", String.class);

                    Role roleUser = Role.valueOf(roles);


                    // if role allowed != role jwt -> UNAUTHORIZED

                    if (!permission.equals(roleUser)) {

                        throw new Exception("no roles");

                    }


                }

            }


        }

        catch (Exception e) {

            e.printStackTrace();

            requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());

        }

    }

}

@JWTTokenNeeded接口:


@javax.ws.rs.NameBinding

@Retention(RUNTIME)

@Target({TYPE, METHOD})

public @interface JWTTokenNeeded {

    Role Permissions() default Role.NoRights;

}

允许角色访问终端节点就像添加@JWTTokenNeeded(Permissions = Role.Admin)


下面是一个示例:


@Path("User")

public class UserResource {

    @EJB

    private UserappDAO userDAO;



    @GET

    @JWTTokenNeeded(Permissions = Role.Admin)

    @Produces("application/json")

    public List<Userapp> all() {

        return userDAO.getAll();

    }

}


查看完整回答
反对 回复 2022-09-22

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信