在JAVA EE 7 Web应用程序(WAR)中,需要“手动”将用户设置为已认证(及其角色)。
基本上,我有一个令牌(JWT)和一组角色(在调用Keycloak授权客户端Java API之后获得)。
获取令牌后,我想将用户设置为已验证(创建安全上下文),因此对安全URL的任何调用都不会返回403 HTTP错误。
在web.xml中仅定义了不同URL映射的角色和安全约束。
已经研究了HttpServletRequest.authenticate方法,但尚未定义(无需)login-config机制。
(不使用Spring或其他框架)。
我的猜测是不可能的,应该使用servlet过滤器来验证安全性(不是web.xml中的安全性约束)
谢谢
答案 0 :(得分:1)
您需要定义一个登录配置。 servlet容器是必需的。 像这样:
{
"policyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Resource": [
"arn:aws:execute-api:us-east-1:1234567:myapiId/staging/POST/*"
],
"Effect": "Allow"
}
]
},
"principalId": "Foo"
}
您的web.xml和HttpServletRequest.authenticate中的应该可以工作。
并且您应该删除此Servlet的安全性约束 因为您尚未管理应用程序中的安全性。
亲切的问候,
拉尔夫
答案 1 :(得分:0)
我最初的解决方案是创建一个servlet过滤器,如果JWT令牌(出现在Authorization标头中)没有所需的角色,则返回UNAUTHORIZED。
更好的方法是创建一个唯一的过滤器,该过滤器在每个需要授权的请求上创建安全上下文。这样,我可以使用@RolesAllowed注释。
要使RolesAllowed注释起作用(否则允许所有请求),重要的是添加 web.xml :
<context-param>
<param-name>resteasy.role.based.security</param-name>
<param-value>true</param-value>
</context-param>
我无法在web.xml中定义任何身份验证约束,否则应用程序甚至会在调用过滤器之前返回403 Forbidden。
安全过滤器:
@Provider
@Priority(Priorities.AUTHENTICATION)
public class SecurityFilter implements ContainerRequestFilter {
@Context private HttpServletRequest httpRequest;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
SecurityContext originalContext = requestContext.getSecurityContext();
// 1. Get token from the request header: "Authorization: Bearer ..."
String token = httpRequest.getHeader("Authorization").substring(7);
// 2. Parse the token to an AccessToken
// calls a utility class which uses org.keycloak.TokenVerifier to get the access token
AccessToken accessToken = KeyCloakUtils.getAccessToken(token);
// 3.- Obtain username and roles
String username = accessToken.getPreferredUsername();
Set<String> roles = accessToken.getRealmAccess().getRoles();
SecurityContext sc = new SecurityContext() {
@Override
public Principal getUserPrincipal() {
return new User(username);
}
@Override
public boolean isUserInRole(String role) {
return roles.contains(role);
}
@Override
public boolean isSecure() {
return originalContext.isSecure();
}
@Override
public String getAuthenticationScheme() {
return "Your Scheme";
}
};
requestContext.setSecurityContext(sc);
}
}
安全方法(界面)的示例:
@POST
@Consumes({ "application/json" })
@Produces({ "application/json" })
@RolesAllowed({"ADMIN_USER"})
public Response createUser(User user);