1

の元の URL を覚えておいてHttp Requestから、ユーザー認証のためにこの要求を Web フォームにリダイレクトする必要があります。認証が成功した場合、ユーザーはoriginal URL上記で覚えた場所にリダイレクトされる必要があります。JBoss 7.1.1 Final、標準web.xml、および JBoss Login Moduleを使用していorg.jboss.security.auth.spi.DatabaseServerLoginModuleます。

私の質問に完全に答えていない次のリンクを参照しました。

ただし、ソリューションを実装した後、カスタム ServerAuthModule はまったく呼び出されません。さらに悪いことに、サーバーから HttpResponse を取得できませんでした。何かが壊れました、助けてください!

私のweb.xml

       <security-constraint>
            <web-resource-collection>
                <web-resource-name>All resources in /pages/*</web-resource-name>
                <description>All resources in /pages/*</description>
                <url-pattern>/pages/*</url-pattern>
                <http-method>GET</http-method>
                <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint>
                <role-name>general</role-name>
            </auth-constraint>
        </security-constraint>

        <security-constraint>
            <display-name>Restrict direct access to the /resources folder.</display-name>
            <web-resource-collection>
                <web-resource-name>The /resources folder.</web-resource-name>
                <url-pattern>/resources/*</url-pattern>
            </web-resource-collection>
            <auth-constraint />
        </security-constraint> 

        <login-config>
            <auth-method>FORM</auth-method>
            <form-login-config>
                <form-login-page>/login.jsf</form-login-page>
                <form-error-page>/loginFailed.jsf</form-error-page>
            </form-login-config>
        </login-config>

        <security-role>
            <role-name>general</role-name>
        </security-role>     

私の jboss-web.xml:

<?xml version="1.0" encoding="UTF-8"?>
    <jboss-web>
        <security-domain>jBossJaasMysqlRealm</security-domain>
         <valve>
           <class-name>org.jboss.as.web.security.jaspi.WebJASPIAuthenticator</class-name>
       </valve>
    </jboss-web>

私のstandalone.xml

 <security-domain name="jBossJaasMysqlRealm" cache-type="default">
                <authentication-jaspi>
                    <login-module-stack name="lm-stack">
                        <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
                            <module-option name="dsJndiName" value="java:/MySqlDS_IamOK"/>
                            <module-option name="principalsQuery" value="select password from  user where username=?"/>
                            <module-option name="rolesQuery" value="select role, 'Roles' from  user_role where  username=?"/>
                        </login-module>
                    </login-module-stack>
                    <auth-module code="at.alex.ok.web.utils.RequestMarkerServerAuthModule" login-module-stack-ref="lm-stack"/>
                </authentication-jaspi>
            </security-domain>

私の習慣WebServerAuthModule:

    import org.jboss.as.web.security.jaspi.modules.WebServerAuthModule;

    public class RequestMarkerServerAuthModule extends WebServerAuthModule {

        public static final String ORIGINAL_URL = "originalURL";

        protected static final Class[] supportedMessageTypes = new Class[] {
                HttpServletRequest.class, HttpServletResponse.class };


        public void initialize(MessagePolicy reqPolicy, MessagePolicy resPolicy,
                CallbackHandler cBH, Map opts) throws AuthException {

            System.out.println( this.getClass().getName() + ".initialize() called");
        }

        public Class[] getSupportedMessageTypes() {
            return supportedMessageTypes;
        }

        public AuthStatus validateRequest(MessageInfo msgInfo, Subject client,
                Subject server) throws AuthException {
            try {
                System.out.println( this.getClass().getName() + ".validateRequest() called");

                processAuthorizationToken(msgInfo, client);
                return AuthStatus.SUCCESS;

            } catch (Exception e) {
                AuthException ae = new AuthException();
                ae.initCause(e);
                throw ae;
            }
        }

        private void processAuthorizationToken(MessageInfo msgInfo, Subject s)
                throws AuthException {

            HttpServletRequest request = (HttpServletRequest) msgInfo
                    .getRequestMessage();

            String originalURL = request.getRequestURL().toString();
            request.getSession().setAttribute(ORIGINAL_URL, originalURL);
        }


        public AuthStatus secureResponse(MessageInfo msgInfo, Subject service)
                throws AuthException {

            System.out.println( this.getClass().getName() + ".secureResponse() called");

            return AuthStatus.SEND_SUCCESS;
        }

        public void cleanSubject(MessageInfo msgInfo, Subject subject)
                throws AuthException {
            System.out.println( this.getClass().getName() + ".cleanSubject() called");

    }

}
4

1 に答える 1

-1

この質問は正しくありません。ログインに成功した後、最初に要求された URL にリダイレクトする場合、JBoss 用のカスタム ServerAuthModule を実装する必要はありません。

インタフェース javax.servlet.RequestDispatcher には定数 FORWARD_REQUEST_URI があります。これは、転送された要求のプロセッサが元の要求 URI を使用できるようにする Http-Request 属性の名前を示します。

JSF 2.2 と View-Scoped バッキング Bean LoginBean を使用して、私の解決策は、次のように、バッキング Bean の @PostConstruct メソッドで最初に要求された URL を取得し、それをセッション属性に格納することです。

@ManagedBean(name="loginBean")
@ViewScoped
public class LoginBean {

    private String originalURL;

    @PostConstruct
    private void init() {
        ExternalContext extCtx = FacesContext.getCurrentInstance().getExternalContext();

        String origURL = (String) extCtx.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);

        HttpServletRequest request = (HttpServletRequest) extCtx.getRequest();
        HttpSession session = (HttpSession)extCtx.getSession(false);

        if (session == null){
            session = (HttpSession)extCtx.getSession(true);
        }

        if (origURL!=null && session.getAttribute(ORIGINAL_URL) == null){
            String applicationName = request.getContextPath();
            origURL = origURL.substring(applicationName.length(), origURL.length());
            session.setAttribute(ORIGINAL_URL, origURL);
        }
    }

次に、同じバッキング Bean の login() メソッドで、次のようにログインが成功した場合に、最初に要求された URL にユーザーをリダイレクトします。

public String login() {

    HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();

    try {
        request.login(this.getLogin(), this.getPassword());
    } catch (ServletException e) {
        // handle bad username / password here
    }

    return this.originalURL + "?faces-redirect=true";
}
于 2016-09-25T03:05:35.760 に答える