Securing REST services in Jersey(在泽西岛保护 REST 服务)
问题描述
I am very much new to web services. I have exposed some REST services using Jersey 2 in integration with Spring. Now I need to secure those rest services using authentication with username/password. I am told not to use Spring Security.
I have no idea of how to do this. I did search on the net but various links show various implementation and I am unable to decide how to proceed with it.
A common way for authenticating with username and password is to use Basic Authentication. Basically the client needs to send a request header Authorization
, with the the header value as Basic Base64Encoded(username:password)
. So is my username is peeskillet
and my password is pass
, I, as a client, should set the header as
Authorization: Basic cGVlc2tpbGxldDpwYXNz
In a servlet environment, the container should have support for Basic authentication. You would configure this support on the web.xml. You can see an example in 48.2 Securing Web Applications of the Java EE tutorial. You will also notice in an example
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
That is for SSL support. This is recommended for Basic Authentication.
If you don't want to deal with the hassle of working with security domains and login modules, realm, and such, that would be required to customize the servlet support, or if you're just not in a servlet environment, implementing Basic Auth in a ContainerRequestFilter
is really not too difficult.
You can see a complete example of how this could be done at jersey/examples/https-clientserver-grizzly. You should focus on the SecurityFilter
The basic flow in the filter goes something like this
Get the
Authorization
header. If it doesn't exist, throw anAuthenticationException
. In which case theAuthenticationExceptionMapper
will send out the header"WWW-Authenticate", "Basic realm="" + e.getRealm() + ""
, which is part of the Basic Auth protocolOnce we have the header, we parse it just to get the Base64 encoded username:password. Then we decode it, then split it, then separate the user name and password. If any of this process fails, again throw the
WebApplicationException
that maps to a 400 Bad Request.Check the username and password. The example source code just checks if the username is
user
and the password ispassword
, but you will want to use some service in the filter to verify this information. If either of these fail, throw anAuthenticationException
If all goes well, a
User
is created from theauthenticate
method, and is injected into anAuthorizer
(which is aSecurityContext
). In JAX-RS, theSecurityContext
is normally used for authorization`.
For the authorization, if you want to secure certain areas for certain resources, you can use the @RolesAllowed
annotation for your classes or methods. Jersey has support for this annotation, by registering the RolesAllowedDynamicFeature
.
What happens under the hood is that the SecurityContext
will be obtained from the request. With the example I linked to, you can see the Authorizer
, it has an overridden method isUserInRole
. This method will be called to check against the value(s) in @RolesAllowed({"ADMIN"})
. So when you create the SecurityContext
, you should make sure to include on the overridden method, the roles of the user.
For testing, you can simply use a browser. If everything is set up correctly, when you try and access the resource, you should see (in Firefox) a dialog as seen in this post. If you use cURL, you could do
C:/>curl -v -u username:password http://localhost:8080/blah/resource
This will send out a Basic Authenticated request. Because of the -v
switch, you should see all the headers involved. If you just want to test with the client API, you can see here how to set it up. In any of the three cases mentioned, the Base64 encoding will be done for you, so you don't have to worry about it.
As for the SSL, you should look into the documentation of your container for information about how to set it up.
这篇关于在泽西岛保护 REST 服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在泽西岛保护 REST 服务
- Jersey REST 客户端:发布多部分数据 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
- 如何使用WebFilter实现授权头检查 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01
- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01