3

JSF を使用する Web アプリケーションがあり、Spring セキュリティがログインと承認に使用されます。

ユーザーが特定のページに入力し、ログインしていない場合、たとえばlocalhost:8080/APP/page.xhtml、アプリケーションはログイン ページにリダイレクトされますが、これで問題ありません。その後、ユーザーはログインしますが、リダイレクト先のページはindex.xhtmlデフォルトのウェルカム ページであり、page.xhtml.

次の動作が必要です。ユーザーはに移動しlocalhost:8080/APP/page.xhtml、ログインするようにリダイレクトされ、その後、目的のページにリダイレクトされる必要があります- page.xhtml.

編集済み - spring-security.xmlのスニペット:

 <security:http auto-config="true">
    <security:intercept-url pattern="/javax.faces.resource/*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <security:intercept-url pattern="/login.xhtml" access="IS_AUTHENTICATED_ANONYMOUSLY"/>

    <security:intercept-url pattern="/**" access="ROLE_UNALLOCATED, ROLE_MANAGER"/>
    <security:intercept-url pattern="/pages/management/" access="ROLE_MANAGER"/>
    <security:intercept-url pattern="/pages/requests/" access="ROLE_UNALLOCATED, ROLE_EMPLOYEE, ROLE_TEAM_LEADER, ROLE_MANAGER"/>

    <security:form-login login-page="/login.xhtml" 
                          />
    <security:logout logout-url="/j_spring_security_logout"
            logout-success-url="/login.xhtml"
            invalidate-session="true"/>
</security:http>

何か案は?ありがとう

編集:

次の理由だと思いました。

 <!-- Welcome page -->
<welcome-file-list>
    <welcome-file>/index.xhtml</welcome-file>
</welcome-file-list>

web.xml から。これを削除しましたが、結果は同じです。

後で編集:

カスタム loginController の行に気付きました。その後、if (authenticationResponseToken.isAuthenticated())ほぼ確実に問題の原因となります。

loginController:

@ManagedBean(name = "loginController")
@SessionScoped
@Controller
public class LoginController implements Serializable {
private static final long serialVersionUID = 1L;

@Autowired
IUserService userService;

@Autowired
@Qualifier("authenticationManager")
protected AuthenticationManager authenticationManager;

// save the current user after login to be able to inject it in other places
// as needed
private User currentUser;

/**
 * This action logs the user in and returns to the secure area.
 * 
 * @return String path to secure area
 */
public String loginUsingSpringAuthenticationManager() {
    // get backing bean for simple redirect form
    LoginFormBackingBean loginFormBean = (LoginFormBackingBean) FacesUtils
            .getBackingBean("loginFormBean");

    // simple token holder
    Authentication authenticationRequestToken = createAuthenticationToken(loginFormBean);

    // authentication action
    try {
        Authentication authenticationResponseToken = authenticationManager
                .authenticate(authenticationRequestToken);

        Authentication authCopy = null;
        final Object principal = authenticationResponseToken.getPrincipal();
        if (principal instanceof LdapUserDetailsImpl) {
            LdapUserDetailsImpl userImpl = (LdapUserDetailsImpl) principal;
            userImpl.getUsername();

            // here check if we already have a User with his DN in the DB
            // get the User by DN
            User u = userService.getUserByDn(userImpl.getDn());

            // if a user with this DN does not exist in the DB, create a new
            // one with the DN from LDAP and the default settings for a new
            // user
            if (null == u) {
                u = userService.createNewUserFromDn(userImpl.getDn(),
                        userImpl.getUsername());
            }
            // set the obtained user as the current user
            setCurrentUser(u);
            List<GrantedAuthority> grAuth = new ArrayList<GrantedAuthority>();
            // after this, do the role authority stuff
            // here loop through user roles if he has more and
            if (null != u.getUserTeamRoles()) {
                for (UserTeamRole urt : u.getUserTeamRoles()) {
                    // here get role for every UserTeamRole
                    grAuth.add(new SimpleGrantedAuthority(urt.getRole()
                            .getName()));
                }
            }

            // add the above found roles to the granted authorities of the
            // current authentication
            authCopy = new UsernamePasswordAuthenticationToken(
                    authenticationResponseToken.getPrincipal(),
                    authenticationResponseToken.getCredentials(), grAuth);
        }

        SecurityContextHolder.getContext().setAuthentication(authCopy);
        // ok, test if authenticated, if yes reroute
        if (authenticationResponseToken.isAuthenticated()) {
            // lookup authentication success url, or find redirect parameter
            // from login bean
            return "index.xhtml?faces-redirect=true";
        }
    } catch (BadCredentialsException badCredentialsException) {
        // FacesMessage facesMessage = new FacesMessage(
        // "Login Failed: please check your username/password and try again.");
        // FacesContext.getCurrentInstance().addMessage(null, facesMessage);
        FacesContext.getCurrentInstance().addMessage(
                null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        "Sample error message",
                        "Login Failed! Please check your credentials"));
    } catch (LockedException lockedException) {
        FacesMessage facesMessage = new FacesMessage(
                "Account Locked: please contact your administrator.");
        FacesContext.getCurrentInstance().addMessage(null, facesMessage);
    } catch (DisabledException disabledException) {
        FacesMessage facesMessage = new FacesMessage(
                "Account Disabled: please contact your administrator.");
        FacesContext.getCurrentInstance().addMessage(null, facesMessage);
    }

    return null;
}

private Authentication createAuthenticationToken(
        LoginFormBackingBean loginFormBean) {
    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
            loginFormBean.getUserName(), loginFormBean.getPassword());
    return usernamePasswordAuthenticationToken;
}

必要なページにリダイレクトするにはどうすればよいですか? ユーザーとパスワードを含むloginBeanがあり、redirectUrlを追加できますが、以前のURLパスを見つけるにはどうすればよいですか?

4

4 に答える 4

5

Spring Securityは、SavedRequestAwareAuthenticationSuccessHandler (カバーの下で HttpSessionRequestCache を使用する) を使用して、AbstractAuthenticationProcessingFilter (通常は UsernamePasswordAuthenticationFilter の具体的な実装を使用) にこのロジックを実装します。(組み込みのサポートを使用するのではなく) 認証するコントローラーを作成したので、このロジックを自分で実装する必要があります。すべてのロジックを自分で実装するのではなく、Spring Security と同じクラスを再利用できます。

たとえば、LoginController は次のように更新される場合があります。

public class LoginController implements Serializable {
    // ... same as before ...
    private RequestCache requestCache = new HttpSessionRequestCache();

    public String loginUsingSpringAuthenticationManager() {
        // ... just as you had been doing ...

        if (authenticationResponseToken.isAuthenticated()) {
            HttpServletRequest request = (HttpServletRequest)         
              FacesContext.getCurrentInstance().getExternalContext().getRequest();
            HttpServletResponse response = (HttpServletResponse)         
              FacesContext.getCurrentInstance().getExternalContext().getResponse();

            SavedRequest savedRequest = requestCache.getRequest(request, response);

            return savedRequest.getRedirectUrl();
        }

        // ... same as you had ...
   }
}
于 2013-01-25T16:26:58.417 に答える
1

デフォルトでは、定義されていない場合、 Spring Security は以前の URL にリダイレクトしようとするため、タグから属性default-target-urlを削除するだけで済みます。default-target-urlform-login

<security:form-login login-page="/login.xhtml" />

アップデート

フィルター チェーンに が含まExceptionTranslationFilterれている場合は、HTTP 要求をキャッシュする必要があります。したがって、カスタム loginController で、このキャッシュされたリクエストからリダイレクト URL を取得しようとすることができます。

RequestCache requestCache = new HttpSessionRequestCache();
SavedRequest savedRequest = requestCache.getRequest(request, response);
String targetUrl = savedRequest.getRedirectUrl();

コントローラーにリクエストを挿入するには、次を試してください。

private @Autowired HttpServletRequest request;

また

HttpServletRequest curRequest = ((ServletRequestAttributes) 
           RequestContextHolder.currentRequestAttributes()) .getRequest();
于 2013-01-22T11:01:32.840 に答える
0

変化する

<security:form-login login-page="/login.xhtml" 
                         default-target-url="/index.xhtml" />

<security:form-login login-page="/login.xhtml" 
                         default-target-url="/page.xhtml" />
于 2013-01-22T10:51:01.440 に答える
0

説明した動作を実現するには、次のように web.xml に春のセキュリティ フィルターを追加する必要があります。

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
</filter-mapping>

また、spring-secruity.xml も編集する必要があるかもしれません。詳細については、このリンクを参照してください: Spring Security with DelegatingFilterProxy

あなたの質問に似ているように見えるこの議論をチェックしてください。セキュリティ-openid-authentic

于 2013-01-24T14:01:02.797 に答える