gpt4 book ai didi

java - 使用 JSR-250 (@RolesAllowed) 注释 Spring MVC 和容器身份验证

转载 作者:行者123 更新时间:2023-12-01 09:01:30 25 4
gpt4 key购买 nike

我有一个 Web 应用程序,它使用 Spring 框架和 Spring MVC 来创建 REST 端点。身份验证由容器使用 Java EE 安全性(特别是由 Active Directory 支持的 Wildfly 9 中的安全领域)提供,并且角色从应用程序数据库加载。我有一个由过滤器应用的请求包装器,以便通过普通的 Servlet API 提供用户详细信息。

web.xml:

<web-app ... version="3.1">

<security-constraint>
<web-resource-collection>
<web-resource-name>Unauthenticated Resources</web-resource-name>
<url-pattern>/favicon.ico</url-pattern>
<url-pattern>/NoAccess.html</url-pattern>
<url-pattern>/login</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/font/*</url-pattern>
<url-pattern>/images/*</url-pattern>
<url-pattern>/js/*</url-pattern>
<url-pattern>/lib/*</url-pattern>
<url-pattern>/partials/*</url-pattern>
</web-resource-collection>
</security-constraint>

<security-constraint>
<web-resource-collection>
<web-resource-name>All Resources</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>FORM</auth-method>
<realm-name>App Realm</realm-name>
<form-login-config>
<form-login-page>/Login.jsp</form-login-page>
<form-error-page>/NoAccess.html</form-error-page>
</form-login-config>
</login-config>

<security-role>
<role-name>*</role-name>
</security-role>

</web-app>

SecurityFilter.java

@WebFilter(urlPatterns = { "*" })
public class SecurityFilter implements Filter {

...

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;

// Don't wrap unauthenticated requests
if (httpRequest.getRemoteUser() == null) {
chain.doFilter(httpRequest, httpResponse);
return;
}

Person user = this.personRepository.findByLogin(httpRequest.getRemoteUser());
if (user != null) {
List<String> roles = this.personRepository.getRoles(user.getId());
HttpServletRequest wrappedRequest = new RequestWrapper(httpRequest, user, roles);
chain.doFilter(wrappedRequest, httpResponse);
} else {
httpResponse.sendRedirect(httpRequest.getContextPath() + "/NoAccess.html");
}
}
}

身份验证有效,并且在 Controller 内,我可以执行 request.getUserPrincipal()request.isUserInRole("SYSTEM_ADMIN") 并且它们正确返回。现在我想向应用程序添加授权。我想在我的 Controller 方法上使用 JSR-250 @RolesPermissed 注释来应用授权规则;我不想在单独的配置文件/类中列出所有规则。 Controller 示例:

@RestController
@RequestMapping("/people")
public class PersonController {

...

@RolesAllowed({Role.SYSTEM_ADMIN, Role.DEPARTMENT_ADMIN, Role.SYSTEM_AUDITOR, Role.AUDITOR})
@RequestMapping
public List<Person> listPeople(HttpServletRequest request) {
return this.personRepository.getPeople();
}
}

当然,这本身没有任何作用,因此我添加了一个带有 @EnableWebSecurity@EnableGlobalMethodSecurity(jsr250Enabled = true) 的配置类。现在,当我点击该资源时,我收到错误org.springframework.security.authentication.AuthenticationCredentialsNotFoundException:在SecurityContext中找不到身份验证对象。很公平,所以我按照 https://gist.github.com/virgium03/86938e43219bc28632d0 中的示例进行操作但我不断收到同样的错误。似乎过滤器永远不会添加到过滤器链中。

我读过很多教程和帖子,但它们几乎都说同样的事情,但对我不起作用。我一定缺少一些简单的东西 - 毕竟,所有信息都可供 Spring Security 做出授权决策。有可能(可能?)我在这里遗漏了一些简单的东西。非常感谢所有帮助!

编辑

我已将以下代码添加到我的 SecurityFilter 类中以填充 Spring 安全上下文。它有效,但我觉得这不是理想的解决方案。

List<GrantedAuthority> authorities = roles.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
PreAuthenticatedAuthenticationToken auth = new PreAuthenticatedAuthenticationToken(user, "", authorities);
auth.setDetails(new WebAuthenticationDetails(wrappedRequest));
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);

最佳答案

问题出在配置的身份验证提供程序上。您正在使用PreAuthenticatedAuthenticationProvider 它从authenticate 方法返回现有的身份验证 token 。因此,如果主体为空,那么它会忽略请求并让其他提供者对其进行身份验证。

authenticate

public Authentication authenticate(Authentication authentication) throws AuthenticationException Authenticate the given PreAuthenticatedAuthenticationToken. If the principal contained in the authentication object is null, the request will be ignored to allow other providers to authenticate it.

基本上,您需要配置另一个 AuthenticationProvider,它将生成身份验证 token 并在 SecurityContext 中设置此 token 。

关于java - 使用 JSR-250 (@RolesAllowed) 注释 Spring MVC 和容器身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41627135/

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