简体   繁体   English

如何在 Java Servlet 上触发 OAuth/OpenID 身份验证并向用户添加我自己的角色?

[英]How can I trigger OAuth/OpenID authentication on a Java Servlet and add my own roles to the user?

On a local Wildfly server I have a simple Java servlet like below:在本地 Wildfly 服务器上,我有一个简单的 Java servlet,如下所示:

import javax.servlet.annotation.HttpMethodConstraint;
import javax.servlet.annotation.ServletSecurity;
import javax.servlet.http.HttpServlet;

@ServletSecurity(httpMethodConstraints = { @HttpMethodConstraint(value = "GET", rolesAllowed = { "debug" })})
public class DebugServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        try ( PrintWriter out = response.getWriter()) {
            /* TODO output your page here. You may use following sample code. */
            ...
            Principal user = request.getUserPrincipal();
            out.println("<p>" + (user != null ? user.getName() : "No user") + "</p>");
            ...
        }
    }
}

I have set up authentication with Wildfly's Elytron v1.17.2 using OpenID Connect (OIDC) with a third party authentication server.我已经使用带有第三方身份验证服务器的 OpenID Connect (OIDC) 设置了 Wildfly 的 Elytron v1.17.2 身份验证。 If it matters, it is not a Keycloak server, and changing the auth server isn't an option;如果重要的话,它不是Keycloak 服务器,并且更改身份验证服务器不是一个选项; using this auth server is a strict business requirement.使用此身份验证服务器是一项严格的业务要求。 The auth server has a bunch of users which we want to give access to, but for my particular client_id none of the users have any roles associated with them, and we want to avoid adding roles through the auth server because the process is...tedious at best. auth 服务器有一堆我们想要授予访问权限的用户,但是对于我的特定 client_id,没有任何用户具有与之关联的任何角色,我们希望避免通过 auth 服务器添加角色,因为该过程是...充其量是乏味的。 Bureaucratic red tape, every time, for every user.官僚繁文缛节,每一次,为每个用户。 Our end goal is to have our own roles in this server's database and we're only going to the 3rd party to handle the login and then verify the login is valid and which user it is.我们的最终目标是在这个服务器的数据库中拥有我们自己的角色,我们只会去第 3 方处理登录,然后验证登录是否有效以及它是哪个用户。

If I include rolesAllowed = { "debug" } in the HttpMethodConstraint, authentication with the 3rd-party auth server gets triggered and works correctly.如果我在 HttpMethodConstraint 中包含rolesAllowed = { "debug" }rolesAllowed = { "debug" }触发与 3rd-party auth 服务器的身份验证并正常工作。 But because none of the users have roles associated with them, they don't have the required "debug" role.但是因为没有一个用户具有与之关联的角色,所以他们没有所需的“调试”角色。 The processRequest method is never reached and the user gets a "Forbidden" error page. processRequest方法永远不会到达,用户会收到“禁止”错误页面。

If I remove or empty the rolesAllowed field of the constraint, authentication with the 3rd-party auth server is not triggered, and there's no UserPrincipal which we can use to identify the user.如果我删除或清空约束的rolesAllowed字段,则不会触发与 3rd-party auth 服务器的身份验证,并且没有可用于识别用户的UserPrincipal

I've tried putting a javax.servlet.Filter in to intercept the request before it gets to my Servlet, but if the "debug" role is required then the filter doesn't get reached either.我试过在请求到达我的 Servlet 之前放入一个javax.servlet.Filter来拦截请求,但是如果需要“调试”角色,那么过滤器也不会到达。 I had hoped to intercept the request after the user authenticates and then add roles to the user, or a session variable, or something which my servlet would then check for permission to do various actions.我曾希望在用户进行身份验证后拦截请求,然后向用户添加角色、会话变量或我的 servlet 将检查执行各种操作的权限的内容。

I've tried a few other combinations which have not triggered authentication:我尝试了其他一些没有触发身份验证的组合:

@ServletSecurity(httpMethodConstraints = { @HttpMethodConstraint(value = "GET", emptyRoleSemantic = ServletSecurity.EmptyRoleSemantic.PERMIT)})

and

@ServletSecurity(httpMethodConstraints = { @HttpMethodConstraint(value = "GET", transportGuarantee = ServletSecurity.TransportGuarantee.CONFIDENTIAL)})

No luck.没运气。

Is there a way I can trigger 3rd-party authentication, and get a UserPrincipal with the authenticated user's username/user id, without requiring a specific role?有没有一种方法可以触发 3rd-party 身份验证,并使用经过身份验证的用户的用户名/用户 ID 获取 UserPrincipal,而无需特定角色? -OR- Is there a way I can add roles to the authenticated user after authenticating but before being blocked by the HttpMethodConstraint? - 或 - 有没有办法在身份验证后但在被 HttpMethodConstraint 阻止之前向经过身份验证的用户添加角色?

The reason your custom filter approach will not work is because the elytron security framework handles this well before your filter chain is invoked.您的自定义过滤器方法不起作用的原因是 elytron 安全框架在调用您的过滤器链之前处理得很好。 You might try custom role mapper within elytron security as explained here (Section 3.2.9) and here to add some predefined roles.您可以按照此处(第 3.2.9 节)和此处的说明在 elytron 安全性中尝试自定义角色映射器,以添加一些预定义的角色。

RoleMapper - After the roles have been decoded for an identity further mapping can be applied, this could be as simple at normalising the format of the names through to adding or removing specific role names. RoleMapper - 在为身份解码角色后,可以应用进一步的映射,这可以很简单地将名称的格式规范化到添加或删除特定的角色名称。

You would obviously need to configure the elytron subsystem to use your custom role mapper.您显然需要配置 elytron 子系统以使用您的自定义角色映射器。 You can take a look at an example configuration for regex-role-mapper here ( in your case you need a custom RoleMapper instead of regex-role-mapper)您可以在此处查看 regex-role-mapper 的示例配置(在您的情况下,您需要自定义 RoleMapper 而不是 regex-role-mapper)

I believe elytrons role mapping is the way to go.我相信 elytrons 角色映射是要走的路。 You could configure a Regex mapper to map every role to one static role.您可以配置一个 Regex 映射器来将每个角色映射到一个静态角色。 Or use the group-decoder-mapper to convert group names into roles.或者使用 group-decoder-mapper 将组名转换为角色。

See for example: https://wildfly-security.github.io/wildfly-elytron/blog/regex-role-mapper/参见例如: https : //wildfly-security.github.io/wildfly-elytron/blog/regex-role-mapper/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM