首页 文章

Wildfly,JAAS和SecurityContext

提问于
浏览
0

我仍然在使用 BASIC auth-method 的Web应用程序中使用Wildfly-9.0.1.Final和JAAS(请参阅我之前的问题Wildfly and JAAS login module) . 当我的自定义登录模块工作时,我遇到了一些授权问题 . 我使用带注释的RESTeasy RESTFul Web服务进行测试,这里是代码:

package it.bytebear.web.mongo;

import it.bytebear.web.mongo.jaas.MongoModuleCallbackHandler;
import it.bytebear.web.mongo.model.User;

import java.security.Principal;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Stateless;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.SecurityContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Path("/service")
Stateless
ublic class UserServices {

    private Logger log = LoggerFactory.getLogger(UserServices.class);

    @GET
    @Path("/userA")
    @RolesAllowed({ "userA" })
    public Response postUserA() {
        return Response.ok("You're user A.", MediaType.TEXT_HTML).build();
    }

    @GET
    @Path("/userB")
    @RolesAllowed({ "userB" })
    public Response postUserB() {
        return Response.ok("You're user B.", MediaType.TEXT_HTML).build();
    }

    @GET
    @Path("/userC")
    @RolesAllowed({ "userC" })
    public Response postUserC() {
        return Response.ok("You're user C.", MediaType.TEXT_HTML).build();
    }

    @POST
    @Path("/login")
    @PermitAll
    @Consumes(MediaType.APPLICATION_JSON)
    // @Consumes("application/x-authc-username-password+json")
    public Response login(User userCredentials) {
        log.info("logging in.");
        try {
            MongoModuleCallbackHandler handler = new MongoModuleCallbackHandler();
            handler.setUsername(userCredentials.getUserName());
            handler.setPassword(userCredentials.getPassword().toCharArray());
            LoginContext loginContext = new LoginContext("MongoLoginRealm", handler);
            loginContext.login();
            Subject subject = loginContext.getSubject();
            List<String> roles = new ArrayList<String>();
            for (Principal p : subject.getPrincipals()) {
                roles.add(p.getName());
            }
            String[] userCredentialsRoles = new String[roles.size()];
            roles.toArray(userCredentialsRoles);
            userCredentials.setRoles(userCredentialsRoles);
            return Response.ok().entity(userCredentials)
                    .type(MediaType.APPLICATION_JSON_TYPE).build();
        } catch (Exception e) {
            log.error("login fails.", e);
            return Response.status(Status.FORBIDDEN).entity("Not logged")
                    .type(MediaType.APPLICATION_JSON_TYPE).build();
        }
    }

    @GET
    @Path("/logout")
    @PermitAll
    public Response logout(Request req) {
        return Response.ok().build();
    }

    @POST
    @Path("/test")
    @PermitAll
    public Response test(@Context SecurityContext ctx) {
        Principal p = ctx.getUserPrincipal();
        return Response.status(Status.OK).entity(p).build();
    }
}

我的登录模块被正确调用并生成一个名为 Roles 的主题,其中包含一个名为 userAPrincipal ,但是当我尝试访问 .../service/userA 时,我总是收到 403 错误 . 我使用 test 方法检查 subjectctx.getUserPrincipal() 总是返回 null . 我想念 LoginModuleSecurityContext 如何工作,怎么 SecurityContext 知道一个主题?更重要的是:我想了解更多,链接到资源和文档将不胜感激 .

更新:在我的 web.xml 我正在使用RESTEasy安全性:

...
<context-param>
<param-name>resteasy.role.based.security</param-name>
<param-value>true</param-value>
</context-param>
...

我是否通过RESTEasy安全性搞乱了EJB安全性?

1 回答

  • 3

    不要实现,配置

    我建议避免以编程方式执行所有JAAS处理 . 只需使用应用程序服务器配置,安全子系统将为您处理所有关联 .

    RestEasy基于角色的安全性

    RestEasy实现基于角色的安全性 . 必须在 web.xml 中的应用程序上下文参数 "resteasy.role.based.security" 中启用它 .

    <context-param>
        <param-name>resteasy.role.based.security</param-name>
        <param-value>true</param-value>
    </context-param>
    

    如果不使用此参数,则只有安全约束(在web.xml中)可供您进行授权配置 .

    示例

    您可以从用于基本安全测试的sample app on GitHub中获取灵感 . 还有Java package with REST resources .

    仍然不相信?

    看一下WildFly的安全子系统实现中的以下代码:

相关问题