always return error 302

I use Spring 4 to create a simple application. Recently, I'm adding Spring Security 3 to the project but always get the Error Code 302 ( so it redirect to home page always ).

Here is my SecurityConfig :

@Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackages = { "com.moon.repository" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("hello").password("world").roles("USER");
}

@Override
public void configure(WebSecurity web) throws Exception {
    web
    .ignoring().antMatchers("/resources/**", "/views/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
            .antMatchers("/","/home").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/home")
            .loginProcessingUrl("/acct/signin")
            .and()
            .logout()
            .permitAll();
}

}

I have a Controller called AccountController :

@Controller
@RequestMapping(value = "/acct")
public class AccountController {

private final Logger logger = LoggerFactory.getLogger(AccountController.class);

@RequestMapping(value = "/signin", method = RequestMethod.POST)
public String signin(@RequestParam("username") String username,
        @RequestParam("password") String password) {

    logger.info("======== [username:{0}][password:{1}] ========", username, password);

    if ("error@1.1".equalsIgnoreCase(username)) {
        return "error";
    } else {
        return "demo";
    }
}

}

My WEB-INF structure:

WEB-INF
----views
--------home.jsp
--------demo.jsp
--------error.jsp

The flow is like:

  • User access the web site with http://mylocal:8080/moon => it shows home.jsp
  • User press the button SignIn and it pops a sub-window asked for username and password => still in home.jsp
  • User press Submit button => I assume it will go /acct/signin and return to /demo, but I see Error 302 in Google Chrome and then it goes to /home again
  • Any ideas ? I'm stuck in 2 full days and now i'm almost in despair...

    thank you very much every one to take a look at my problem

    =================================== 1st Update ===================================

    Update: The form in home.jsp

    <form:form role="form" method="POST" action="acct/signin"
    class="form-signin">
    <div class="row">
        <div class="col-lg-5">
            <input name="username" size="20" type="email"
                class="form-control" placeholder="Email address" required
                autofocus> 
                <input name="password" type="password"
                        class="form-control" placeholder="Password" required>
                    <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
        </div>
    </div>
    </form:form>
    

    =================================== 2nd Update ===================================

    I tried to implement UserDetailsService(not to use in-memory auth) but still... the same problem - Error 302

    AppUserDetailsServiceImpl.java

    @Component
    public class AppUserDetailsServiceImpl implements UserDetailsService {
    
        private final Logger logger = LoggerFactory.getLogger(AppUserDetailsServiceImpl.class);
    
        @Override
        public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
    
            logger.info("loadUserByUsername username=" + username);
            logger.info("======== {} ========",SecurityContextHolder.getContext().getAuthentication());
    
            if (!username.equals("hello")) {
                throw new UsernameNotFoundException(username + " not found");
            }
    
            // creating dummy user details
            return new UserDetails() {
    
                private static final long serialVersionUID = 2059202961588104658L;
    
                @Override
                public boolean isEnabled() {
                    return true;
                }
    
                @Override
                public boolean isCredentialsNonExpired() {
                    return true;
                }
    
                @Override
                public boolean isAccountNonLocked() {
                    return true;
                }
    
                @Override
                public boolean isAccountNonExpired() {
                    return true;
                }
    
                @Override
                public String getUsername() {
                    return username;
                }
    
                @Override
                public String getPassword() {
                    return "world";
                }
    
                @Override
                public Collection<? extends GrantedAuthority> getAuthorities() {
                    List<SimpleGrantedAuthority> auths = new java.util.ArrayList<SimpleGrantedAuthority>();
                    auths.add(new SimpleGrantedAuthority("USER"));
                    return auths;
                }
            };
        }
    

    The log shows:

    [14/08/19 15:16:32:200][INFO ][com.moon.repository.AppUserDetailsServiceImpl][loadUserByUsername](24) loadUserByUsername username=hello
    [14/08/19 15:16:32:200][INFO ][com.moon.repository.AppUserDetailsServiceImpl][loadUserByUsername](25) ======== org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f1e4f742: Principal: com.moon.repository.AppUserDetailsServiceImpl$1@e3dc1b1; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@12afc: RemoteIpAddress: 127.0.0.1; SessionId: 023BC9A8B997ECBD826DD7C33AF55FC7; Granted Authorities: USER ========
    

    I believe Spring is redirecting you to /home because you didn't actually authenticated a User through the login process.

  • You access your web-app through http://mylocal:8080/moon returning the home.jsp view
  • You click the SignIn button, submitting your login form since no form login is explicitly declared, Spring Security will display the username and password prompt box for the end-user to enter its credentials
  • These credentials are then POSTed to the login processing URL ( /acct/signin ) for which you happen to have a mapping with the signin method in the AccountController
  • Such controller fails to authenticate a User the Spring way, but still redirect the request to /demo by returning a String
  • The /demo path is protected ( .anyRequest().authenticated() ) to any unauthenticated user, since the current user is indeed unauthenticated, Spring Security will automatically redirect the request to the login page
  • You end up on /home ( .loginPage("/home") )
  • Using a InMemoryUserDetailsManagerConfigurer (see inMemoryAuthentication javadoc), you can only successfully login through the configured credentials. If you want a fully-fledged Authentication system, you must provide an UserDetailsService implementation to your Spring Security configuration (through the userDetailsService method).


    EDIT : Following the conversation with chialin.lin, it seems the missing configuration was a defaultSuccessfulUrl for Spring Security to know where to redirect the user once authenticated.


    为了避免必须创建一个新的繁琐的SuccessHandler,请在您的Filter中重写successfulAuthentication方法,并在SecurityContext上设置Authentication之后调用chain.dofilter()。

    链接地址: http://www.djcxy.com/p/80956.html

    上一篇: jqplot邻居问题

    下一篇: 总是返回错误302