Java JAX-RS:如何保护 REST 端点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18086048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:17:51  来源:igfitidea点击:

JAX-RS: How to secure REST endpoints?

javarestauthenticationjbossjax-rs

提问by daydreamer

I am using JBoss ASand JAX-RSfor creating RESTendpoints.

我正在使用JBoss ASJAX-RS用于创建REST端点。

Lets say my class looks like

可以说我的班级看起来像

@Path("/users")
public class UserResource {


  @GET
  public Response getAccount() {
    return "hello";
  }
}

Now getAccountis not authenticated at the moment

现在getAccount暂时未通过身份验证

Wanted
- I would like to add authentication so that when code hits getAccountthe user is authenticated
- I would like the authentication to be driven by annotations instead of XML configurations, if at all possible
- I would like to do the database comparison to see if the user is valid

想要
- 我想添加身份验证,以便在代码命中时getAccount对用户进行身份验证
- 我希望身份验证由注释而不是 XML 配置驱动,如果可能的话
- 我想进行数据库比较以查看是否用户有效

Problem
- I have never done that so I have no idea how to implement it
- I have googled around a lot and found Jersey examples

问题
- 我从来没有这样做过,所以我不知道如何实现它
- 我在谷歌上搜索了很多并找到了泽西岛的例子

UPDATE
- I would like to send authentication credentials with each request and notcreating any session

更新
- 我想随每个请求发送身份验证凭据,而不是创建任何会话

Please guide me with one simple working example and I would try to extend from there

请用一个简单的工作示例指导我,我会尝试从那里扩展

采纳答案by daydreamer

I solved this with following code.

我用以下代码解决了这个问题。

noteToken mechanism will be updated once I do that

注意令牌机制将在我这样做后更新

I have solved this by modifying the interceptor I have, the following is code

我已经通过修改我拥有的拦截器解决了这个问题,以下是代码

Annotation

注解

@Inherited
@InterceptorBinding
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface SecurityChecked {

}

Resource Class

资源类

public class SecureResource {

    @GET
    @SecurityChecked
    public Response getUser() {
        return Response.ok("authenticated successfully!").build();
    }
}

Interceptor class

拦截器类

@Interceptor
@Provider
@ServerInterceptor
@SecurityChecked
public class SecurityCheckInterceptor implements PreProcessInterceptor, AcceptedByMethod {
    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityCheckInterceptor.class);

    @Nullable
    @Override
    public ServerResponse preProcess(final HttpRequest request, final ResourceMethod method) throws Failure, WebApplicationException {
        final List<String> authToken = request.getHttpHeaders().getRequestHeader("X-AUTH");

        if (authToken == null || !isValidToken(authToken.get(0))) {
            final ServerResponse serverResponse = new ServerResponse();
            serverResponse.setStatus(Response.Status.UNAUTHORIZED.getStatusCode());
            return serverResponse;
        }

        return null;
    }

    private static boolean isValidToken(@Nonnull final String authToken) {
        LOGGER.info("validating token: " + authToken);
        return true;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public boolean accept(final Class declaring, final Method method) {
        // return declaring.isAnnotationPresent(SecurityChecked.class); // if annotation on class
        return method.isAnnotationPresent(SecurityChecked.class);
    }
}

and then I run my Integration tests by deploying the resource class in JBoss and issuing following commands on command-line

然后我通过在 JBoss 中部署资源类并在命令行上发出以下命令来运行我的集成测试

curl --header 'X-AUTH: 1a629d035831feadOOO4uFReLyEW8aTmrCS' http://localhost:8080/market-1.0-SNAPSHOT/rest/login
curl --header 'InvalidHeader: InvalidHeaderValue' http://localhost:8080/market-1.0-SNAPSHOT/rest/login

回答by Rakesh Waghela

You need is a Stateless Spring Security configuration in front of your JAX RS end points. I have addressed exact problem you are trying to solve but I don't have my own code to share..

您需要在 JAX RS 端点前进行无状态 Spring Security 配置。我已经解决了您正在尝试解决的确切问题,但我没有自己的代码可以共享..

Here is one project which has done the exact thing you are asking, Some wise man has done it all for you ;)

这是一个项目,它确实完成了您所要求的事情,某个聪明人已经为您完成了这一切;)

https://github.com/philipsorst/angular-rest-springsecurity

https://github.com/philipsorst/angular-rest-springsecurity

What is the magic ?

什么是魔法?

  1. You have one unprotected URL which does the Authentication, and set the user roles as well..
  2. Then you return some kind of Token, put it some where in cache which will be expected on every subsequent call..
  3. Upon new request on other protected resources, you will check if the Token is present in your cache/session store ( you need some mechanism to keep track of valid tokens )
  4. If token is resent and valid, you do the programmatic Log-in in Spring Security which ensures that you can use all the Security features spring provides, ( Annotations, JSTL Tags etc.. ) !
  5. Once passed token validation you will get the logged in user details in your controllers ( aka JAX RS resources ) to deal with security further..
  6. If the token was not valid or not present , it would be trapped by failure end point which would return appropriate response ( 401 )
  1. 您有一个不受保护的 URL 进行身份验证,并设置用户角色。
  2. 然后你返回某种令牌,把它放在缓存中的某个位置,这在每次后续调用中都会出现。
  3. 根据对其他受保护资源的新请求,您将检查缓存/会话存储中是否存在令牌(您需要某种机制来跟踪有效令牌)
  4. 如果令牌重新发送且有效,则在 Spring Security 中执行程序化登录,以确保您可以使用 spring 提供的所有安全功能(注释、JSTL 标签等)!
  5. 通过令牌验证后,您将在控制器(又名 JAX RS 资源)中获得登录的用户详细信息,以进一步处理安全问题。
  6. 如果令牌无效或不存在,它将被失败端点捕获,该端点将返回适当的响应(401)

Refer Following Link To Understand How Stateless Spring Security is configured..,https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/resources/context.xml

请参阅以下链接以了解如何配置无状态 Spring Security..,https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/resources/context.xml

See how a user is validated for the first time and a token is generated..https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/java/net/dontdrinkandroot/example/angularrestspringsecurity/rest/resources/UserResource.java

查看如何首次验证用户并生成令牌.. https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/java/net/dontdrinkandroot/example/angularrestspringsecurity /rest/resources/UserResource.java

Here is the class where programmatic login is performed on every request after token check..https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/java/net/dontdrinkandroot/example/angularrestspringsecurity/rest/AuthenticationTokenProcessingFilter.java

这是令牌检查后对每个请求执行程序化登录的类.. https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/java/net/dontdrinkandroot/example/angularrestspringsecurity /rest/AuthenticationTokenProcessingFilter.java