JSF with Spring security - redirect to specified page after login

I have a web application that uses JSF and Spring to consume and authorize.

When a user types a certain page and he is not logged in, for example. localhost:8080/APP/page.xhtml

, the app is redirected to the login page, which is fine. After that, the user logs in, but the page they are redirected to is index.xhtml

which is the default welcome page, not page.xhtml

.

I need the following behavior: the user navigates to localhost:8080/APP/page.xhtml

, he is redirected to login, after which he should be redirected to the desired page - page.xhtml

.

Edited - snippet of 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>

      

Any ideas? Thanks to

Edit:

I thought it was because:

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

      

from web.xml. I removed this but with the same result.

Edit later:

I just noticed a line in my custom loginController after if (authenticationResponseToken.isAuthenticated())

which is almost certainly the source of the problem:

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;
}

      

How can I redirect to the page I want? I have a loginBean that contains a user and password and I could add a redirectUrl, but how do I find the previous url?

+3


source to share


5 answers


Spring Security implements this logic for you in an AbstractAuthenticationProcessingFilter (usually using a concrete UserPasswordAuthenticationFilter implementation) using the SavedRequestAwareAuthenticationSuccessHandler (which uses the HttpSessionRequestCache under the covers). Since you wrote a controller for authentication (instead of using built-in support), you will need to implement this logic yourself. Instead of implementing all the logic yourself, you can reuse the same Spring Security classes.

For example, your LoginController can be updated like this:



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 ...
   }
}

      

+5


source


By default, if default-target-url

not defined, Spring Security tries to redirect to the previous url, so you just need to remove the attribute default-target-url

from the tag form-login

.

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

      

Update

If your filter chain has ExceptionTranslationFilter

, then it should cache the HTTP request. So, in your custom loginController, you can try to get the redirect url from that cached request.

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

      



To request a request for a controller, follow these steps:

private @Autowired HttpServletRequest request;

      

or

HttpServletRequest curRequest = ((ServletRequestAttributes) 
           RequestContextHolder.currentRequestAttributes()) .getRequest();

      

+1


source


Edit

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

      

to

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

      

0


source


To describe the behavior, you must add a spring security filter to your web.xml like this:

<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>

      

You might also need to edit your spring-security.xml. see this link for more information: Spring Security with DelegationFilterProxy

Check this discussion, it looks like it is similar to your question, maybe this will help you: http://forum.springsource.org/showthread.php?128480-Redirecting-to-original-(unauthenticated-page)-after-spring-security -openid-authentic

I hope this is the answer to your question;)

Aymen

0


source


I think I had this problem before.

The only solution I found was to set the welcome page to index.jsp and then redirect the user to that page as shown below:

<body>
  <jsp:forward page="page.jsf"/>
</body>

      

(I assume index.jsp and page.xhtml are on the same path level).

I hope this help;)

Hello,

Aymen

-2


source







All Articles