首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >servlet以编程方式设置身份验证

servlet以编程方式设置身份验证
EN

Stack Overflow用户
提问于 2019-08-23 09:54:43
回答 2查看 1.1K关注 0票数 1

在JAVA 7 web应用程序(WAR)中,需要“手动”将用户设置为经过身份验证的(及其角色)。

基本上,我有一个令牌(JWT)和一组角色(在调用Keycloak授权客户端Java之后获得)。

在我得到令牌之后,希望将用户设置为身份验证(创建安全上下文),这样对安全URL的任何调用都不会返回403 HTTP错误。

在web.xml中定义了不同URL映射的角色和安全性约束。

查看了HttpServletRequest.authenticate方法,但没有定义登录-配置机制(不需要)。

(不使用Spring或其他框架)。

我猜这是不可能的,应该使用servlet过滤器来验证安全性(不是web.xml中的安全约束)。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-05 15:42:55

我的最初解决方案是创建一个servlet过滤器,如果JWT令牌(在授权头中)不具备所需的角色,它将返回未经授权的内容。

更好的方法是创建一个唯一的过滤器,为每个需要授权的请求创建安全上下文。有了这个,我可以使用@RolesAllowed注释。

要使RolesAllowed注释工作(否则所有请求都允许),重要的是要添加到web.xml中。

代码语言:javascript
复制
<context-param>
  <param-name>resteasy.role.based.security</param-name>
  <param-value>true</param-value>
</context-param>

我不能在web.xml中定义任何auth约束,否则应用程序会在过滤器被调用之前返回403个禁忌。

安全过滤器:

代码语言:javascript
复制
@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);
    }
}

安全方法(接口)示例:

代码语言:javascript
复制
@POST
@Consumes({ "application/json" })
@Produces({ "application/json" })
@RolesAllowed({"ADMIN_USER"})
public Response createUser(User user);
票数 0
EN

Stack Overflow用户

发布于 2019-08-23 10:03:27

您需要定义一个登录配置。对于servlet容器来说,这是必要的。放上这样的东西:

代码语言:javascript
复制
<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>default</realm-name>
</login-config>

在您的web.xml和HttpServletRequest.authenticate中应该可以工作。

并且您应该删除这个servlet的安全约束,因为如果还没有完成,您应该管理应用程序中的安全性。

致以亲切的问候,

拉尔夫

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57623850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档