如何通过Servlet进行seam-authenticate

时间:2021-05-27 19:59:35

I know it's not the way it's meant to be and it's totally wrong, but orders are orders, I need to do the following: The user access the servlet with the accesskey on the parameters, like this:

我知道这不是它的意思,它是完全错误的,但订单是订单,我需要执行以下操作:用户使用参数上的accesskey访问servlet,如下所示:

http://myhost/my_app/servlet?accesskey=XXXXX

The servlet then gets the key and authenticate the user on seam with it, is it possible? I couldn't manage to do it so far

然后,servlet获取密钥并使用它在接缝上验证用户,是否可能?到目前为止我无法做到这一点

2 个解决方案

#1


0  

From your question it is not clear if you are required to create a custom servlet or you just need to make login based on a request parameter. The main difference is that a custom servlet is not intercepted by Seam and you cannot use components unless you manually start a seam lifecycle (as noted by Trind, you need to use LifeCycle.beginCall() and LifeCycle.endCall() to be able to use Seam components when calling from outside SeamFilter). Other than that, the two solutions work similarly.

根据您的问题,不清楚您是否需要创建自定义servlet,或者您只需要根据请求参数进行登录。主要的区别是Seam没有拦截自定义servlet,除非你手动启动一个seam生命周期,否则你不能使用组件(如Trind所述,你需要使用LifeCycle.beginCall()和LifeCycle.endCall()才能从SeamFilter外部调用时使用Seam组件。除此之外,这两种解决方案的工作方式类似。

Create a component that will handle authentication:

创建一个将处理身份验证的组件:

@Name("myAuthenticator")
public class MyAuthenticator implements Serializable {

    // Seam's identity component
    @In private transient Identity identity;

    // When logged in, the user needs to have some roles, usually
    // you assign these dynamically based on user name, type, etc., here
    // I just initialize it to a fixed list of roles
    ArrayList<String> roles = new ArrayList<String>(Arrays.toList(
            new String[] { "base", "admin" }));

    // Access key (getters and setters omitted but are necessary)
    private String accessKey;

    public String doAuth() {
        // Check accessKey validity (against an SSO service or 
        // in your DB or whatever), here we do a trivial check.
        boolean userCanAccess = "ADMINKEY".equals(accessKey);

        if (userCanAccess) {
            identity.acceptExternallyAuthenticatedPrincipal(
                    new SimplePrincipal("username"));

            // Assign user roles
            for (String role : roles) {
                identity.addRole(role);
            }
            return "ok";
        }
        return "ko";
    }
}

Now create a login page descriptor that will handle login via the parameter (say externalLogin.page.xml, you don't need to create an .xhtml page for this):

现在创建一个登录页面描述符,它将通过参数处理登录(比如externalLogin.page.xml,你不需要为此创建一个.xhtml页面):

<page>
    <!-- this sets the accessKey variable with the query parameter -->
    <param name="accessKey" value="#{myAuthenticator.accessKey}" />

    <!-- this invokes our authentication action -->
    <action execute="#{myAuthenticator.doAuth}" />

    <!-- navigation rules, these determine what to do if auth is ok or fails -->
    <navigation from-action="#{myAuthenticator.doAuth}">
        <rule if-outcome="ko">
            <redirect view-id="/error.xhtml">
                <message severity="ERROR">Invalid Authentication Key</message>
            </redirect>
        </rule>
        <rule if-outcome="ok">
            <redirect view-id="/home.xhtml">
                <message severity="INFO">Welcome!</message>
            </redirect>
        </rule>
    </navigation>
</page>

Now to perform login you can use that page, like so:

现在要执行登录,您可以使用该页面,如下所示:

http://localhost:8080/yourapp/externalLogin.seam?accessKey=XXXXXXXX

If you need to use a custom servlet (very unlikely, but nevertheless), the above component does not change, just call it from within the servlet like this:

如果你需要使用自定义servlet(非常不可能,但仍然如此),上面的组件不会改变,只需从servlet中调用它,如下所示:

public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    // Start Seam lifecycle
    LifeCycle.beginCall();
    // Get an instance of the authenticator component from Seam
    MyAuthenticator auth = Component.getInstance("myAuthenticator");
    // Set access key in component and perform auth
    auth.setAccessKey(req.getParameter("accessKey"));
    String result = auth.doAuth();
    // End Seam lifecycle, no more component calls are needed.
    LifeCycle.endCall();

    // Do something here with the result
    if ("ok".equals(result)) {
        resp.sendRedirect(...);
    }
}

#2


0  

This code in your servlet should make you able to access your seam components.

servlet中的这段代码应该能够访问你的seam组件。

Lifecycle.beginCall();

Authenticator authenticator = (Authenticator)Component.getInstance("authenticator");

LifeCycle.endCall();

#1


0  

From your question it is not clear if you are required to create a custom servlet or you just need to make login based on a request parameter. The main difference is that a custom servlet is not intercepted by Seam and you cannot use components unless you manually start a seam lifecycle (as noted by Trind, you need to use LifeCycle.beginCall() and LifeCycle.endCall() to be able to use Seam components when calling from outside SeamFilter). Other than that, the two solutions work similarly.

根据您的问题,不清楚您是否需要创建自定义servlet,或者您只需要根据请求参数进行登录。主要的区别是Seam没有拦截自定义servlet,除非你手动启动一个seam生命周期,否则你不能使用组件(如Trind所述,你需要使用LifeCycle.beginCall()和LifeCycle.endCall()才能从SeamFilter外部调用时使用Seam组件。除此之外,这两种解决方案的工作方式类似。

Create a component that will handle authentication:

创建一个将处理身份验证的组件:

@Name("myAuthenticator")
public class MyAuthenticator implements Serializable {

    // Seam's identity component
    @In private transient Identity identity;

    // When logged in, the user needs to have some roles, usually
    // you assign these dynamically based on user name, type, etc., here
    // I just initialize it to a fixed list of roles
    ArrayList<String> roles = new ArrayList<String>(Arrays.toList(
            new String[] { "base", "admin" }));

    // Access key (getters and setters omitted but are necessary)
    private String accessKey;

    public String doAuth() {
        // Check accessKey validity (against an SSO service or 
        // in your DB or whatever), here we do a trivial check.
        boolean userCanAccess = "ADMINKEY".equals(accessKey);

        if (userCanAccess) {
            identity.acceptExternallyAuthenticatedPrincipal(
                    new SimplePrincipal("username"));

            // Assign user roles
            for (String role : roles) {
                identity.addRole(role);
            }
            return "ok";
        }
        return "ko";
    }
}

Now create a login page descriptor that will handle login via the parameter (say externalLogin.page.xml, you don't need to create an .xhtml page for this):

现在创建一个登录页面描述符,它将通过参数处理登录(比如externalLogin.page.xml,你不需要为此创建一个.xhtml页面):

<page>
    <!-- this sets the accessKey variable with the query parameter -->
    <param name="accessKey" value="#{myAuthenticator.accessKey}" />

    <!-- this invokes our authentication action -->
    <action execute="#{myAuthenticator.doAuth}" />

    <!-- navigation rules, these determine what to do if auth is ok or fails -->
    <navigation from-action="#{myAuthenticator.doAuth}">
        <rule if-outcome="ko">
            <redirect view-id="/error.xhtml">
                <message severity="ERROR">Invalid Authentication Key</message>
            </redirect>
        </rule>
        <rule if-outcome="ok">
            <redirect view-id="/home.xhtml">
                <message severity="INFO">Welcome!</message>
            </redirect>
        </rule>
    </navigation>
</page>

Now to perform login you can use that page, like so:

现在要执行登录,您可以使用该页面,如下所示:

http://localhost:8080/yourapp/externalLogin.seam?accessKey=XXXXXXXX

If you need to use a custom servlet (very unlikely, but nevertheless), the above component does not change, just call it from within the servlet like this:

如果你需要使用自定义servlet(非常不可能,但仍然如此),上面的组件不会改变,只需从servlet中调用它,如下所示:

public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    // Start Seam lifecycle
    LifeCycle.beginCall();
    // Get an instance of the authenticator component from Seam
    MyAuthenticator auth = Component.getInstance("myAuthenticator");
    // Set access key in component and perform auth
    auth.setAccessKey(req.getParameter("accessKey"));
    String result = auth.doAuth();
    // End Seam lifecycle, no more component calls are needed.
    LifeCycle.endCall();

    // Do something here with the result
    if ("ok".equals(result)) {
        resp.sendRedirect(...);
    }
}

#2


0  

This code in your servlet should make you able to access your seam components.

servlet中的这段代码应该能够访问你的seam组件。

Lifecycle.beginCall();

Authenticator authenticator = (Authenticator)Component.getInstance("authenticator");

LifeCycle.endCall();