gpt4 book ai didi

java - JAX-RS 安全性 - 主体不持久

转载 作者:行者123 更新时间:2023-11-30 07:46:28 25 4
gpt4 key购买 nike

首先是代码:

应用设置类:

    @ApplicationPath("/rest")
public class ApplicationConfig extends Application {

}

JAX-RS 资源类:

    @Path("/test")
@RequestScoped
public class TestWS {
@POST
@Path("/login")
@Produces(MediaType.TEXT_PLAIN)
public Response login(@Context HttpServletRequest req){
req.getSession().setAttribute("test","test");
System.out.println(req.getSession().getId());
if(req.getUserPrincipal() == null){
String authHeader = req.getHeader(HttpHeaders.AUTHORIZATION);
if(authHeader != null && !authHeader.isEmpty()){
String base64Credentials = authHeader.substring("Basic".length()).trim();
String credentials = new String(Base64.getDecoder().decode(base64Credentials),
Charset.forName("UTF-8"));
final String[] values = credentials.split(":",2);
try {
req.login(values[0], values[1]);
System.out.println(req.getUserPrincipal().toString());
}
catch(ServletException e){
e.printStackTrace();
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
}else{
System.out.println(req.getUserPrincipal());
System.out.println(req.isUserInRole("User"));
req.getServletContext().log("Skipped logged because already logged in!");
}

req.getServletContext().log("Authentication Demo: successfully retrieved User Profile!");
return Response.ok().build();
}

@Path("/ping")
@Produces(MediaType.APPLICATION_JSON)
@GET
public String ping(@Context HttpServletRequest req){
Object test = req.getSession().getAttribute("test");
System.out.println(req.getSession().getId());
System.out.println(test);
System.out.println(req.getUserPrincipal());
System.out.println(req.isUserInRole("User"));
return "{\"status\":\"ok\"}";
}
}

web.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
<web-app>
<context-param>
<param-name>resteasy.role.based.security</param-name>
<param-value>true</param-value>
</context-param>

<security-constraint>
<web-resource-collection>
<web-resource-name>rest</web-resource-name>
<url-pattern>/rest/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>

<session-config>
<session-timeout>30</session-timeout>
</session-config>

<login-config>
<auth-method>BASIC</auth-method>
<realm-name>PBKDF2DatabaseDomain</realm-name>
</login-config>
</web-app>

jboss-web.xml

    <?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<context-root>/</context-root>
<security-domain>PBKDF2DatabaseDomain</security-domain>
</jboss-web>

standalone.xml 中的安全设置

    <subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
<security-domain name="PBKDF2DatabaseDomain" cache-type="default">
<authentication>
<login-module code="de.rtner.security.auth.spi.SaltedDatabaseServerLoginModule" flag="required" module="de.rtner.PBKDF2">
<module-option name="dsJndiName" value="java:jboss/datasources/developmentDS"/>
<module-option name="principalsQuery" value="SELECT password FROM ur.user WHERE username=?"/>
<module-option name="rolesQuery" value="select distinct r.NAME, 'Roles' from ur.user_roles ur left join ur.ct_role r on ur.ROLE_ID = r.ID left join ur.user u on ur.USER_ID = u.ID where u.username =?"/>
</login-module>
</authentication>
</security-domain>
...

现在我的问题是,在请求中使用带有 BASIC auth header 的/login 方法后,我已经获得了用户主体,因此它打印出来:

由于已经登录而跳过登录!

如果我从请求中删除 BASIC auth header 并再次调用登录,我仍然会得到相同的打印输出 - 所以我已经在请求中拥有用户主体 - 无需 req.login。

但是如果我调用 ping 方法,即使 session id 相同且 session 属性已设置,用户主体也为 null。我究竟做错了什么?我希望用户主体能够像在/login 上一样在/ping 上持续存在。

我正在使用 Wildfly 10(RESTeasy jax-rs 实现)

我的问题类似于: JBOSS AS7 jax-rs jaas and annotations

但是修复 - 在登录方法中设置 session 属性对我不起作用。

最佳答案

一些提示和评论:

  • 由于 REST 是无状态的,我将在客户端管理 session ,而不是在服务器端保留客户端状态。
  • 可以通过为您希望仅限于经过身份验证的用户(例如/login 和/ping)的每个请求/服务发回 BASIC 身份验证 header 来实现无状态身份验证
  • 当用户未经过良好的身份验证和识别时,/login 服务可能会抛出 WebApplicationException,以便您的客户端应用程序对其进行管理并向最终用户显示身份验证错误消息。然后,您可以在/ping 方法上方使用 @RolesAllowed('something') 注释和 JAAS 来限制对具有 'something' 角色的经过身份验证的用户的访问。因此,您不再需要编写身份验证或授权代码,并可以从应用中的授权层中受益。

所有这一切都可以通过 Java EE 7 在 Wildfly 上实现,无需额外的库。

关于java - JAX-RS 安全性 - 主体不持久,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33866597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com