修改
我的猜测是,原始网址请求首先是“/”,因此在成功登录时,用户登陆到“/”。
如果用户在登录前输入了site.com/someOtherUrl,则登录成功后他将登陆site.com/someOtherUrl。如何解决/
编辑结束 -
当用户来时,为mysite.com
或localhosr:8080
,
他登陆/login
页面然后输入凭据并按下登录按钮。
现在他实际上已登录。他应该降落在/users/home
但他登陆 /
此时,当他登录时,他可以使用地址栏手动转到/users/home
。
不知情的用户(关于问题)会点击后退按钮并再次登录,然后按照他应该的方式登陆到正确的网址/users/home
问题是,为什么不是第一次?为什么他第一次登陆“/”而不是/ users / home尽管他已登录?
弹簧security.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- This is where we configure Spring-Security -->
<security:http auto-config="true" use-expressions="true" access-denied-page="/loginfail" >
<security:intercept-url pattern="/" access="permitAll"/>
<security:intercept-url pattern="/favicon.ico" access="permitAll"/> <!-- lolz -->
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/logout" access="permitAll"/>
<security:intercept-url pattern="/loginfail" access="permitAll"/>
<security:intercept-url pattern="/resources/**" access="permitAll"/>
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<security:form-login
login-page="/login"
authentication-failure-url="/login?error=true"
default-target-url="/users/home"/>
<!-- authentication-failure-url="/loginfail?error=true" -->
<security:logout
invalidate-session="true"
logout-success-url="/login"
logout-url="/logout"/>
</security:http>
<!-- Declare an authentication-manager to use a custom userDetailsService -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="customUserDetailsService">
<!-- <security:password-encoder ref="passwordEncoder"/>-->
</security:authentication-provider>
</security:authentication-manager>
<!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database
<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
-->
<!-- A custom service where Spring will retrieve users and their corresponding access levels -->
<bean id="customUserDetailsService" class="web.service.common.CustomUserDetailsService"/>
<!--For loging security activity-->
<!--<bean id="loggerListener" class="org.springframework.security.authentication.event.LoggerListener" />-->
</beans>
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<welcome-file-list>
<!--<welcome-file>login</welcome-file> -->
<welcome-file>login.jsp</welcome-file>
<!--<welcome-file>redirect.jsp</welcome-file>-->
<!--<welcome-file>WEB-INF/view/jsp/login/login.jsp</welcome-file>-->
</welcome-file-list>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<!-- <welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>-->
<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>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
</web-app>
CustomUserDetailsService
package web.service.common;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import web.dao.UsersDAO;
import web.dao.impl.jpa.UsersDAOImpl;
import web.entity.Users;
@Service
public class CustomUserDetailsService implements UserDetailsService{
//@Resource
@Autowired
private UsersDAO userDAO;
/**
* Retrieves a springUser record containing the springUser's credentials and access.
*/
public UserDetails loadUserByUsername(String email)
throws UsernameNotFoundException, DataAccessException {
// Declare a null Spring User
UserDetails springUser = null;
try {
System.out.println("the email passed from CustomUserDetailsService in method loadUserByUsername is: " +email);
// Search database for a springUser that matches the specified email
// You can provide a custom DAO to access your persistence layer
// Or use JDBC to access your database
// DbUser is our custom domain springUser. This is not the same as Spring's User
System.out.println("debug ---- 1");
Users dbUser = userDAO.getUserByLoginId(email);
// Populate the Spring User object with details from the dbUser
// Here we just pass the email, password, and access level
// getAuthorities() will translate the access level to the correct role type
System.out.println("debug ---- 2");
springUser = new User(
dbUser.getEmail(),
dbUser.getPassword().toLowerCase(),
true,
true,
true,
true,
//getAuthorities(dbUser.getAccess()) );
getAuthorities(2) );
System.out.println("debug ---- 3");
} catch (Exception e) {
System.out.println("print Error in retrieving user");
e.printStackTrace();
System.out.println(e.getMessage());
throw new UsernameNotFoundException("Error in retrieving user");
}
System.out.println("debug ---- 4");
// Return springUser to Spring for processing.
// Take note we're not the one evaluating whether this springUser is authenticated or valid
// We just merely retrieve a springUser that matches the specified email
return springUser;
}
/**
* Retrieves the correct ROLE type depending on the access level, where access level is an Integer.
* Basically, this interprets the access value whether it's for a regular springUser or admin.
*
* @param access an integer value representing the access of the springUser
* @return collection of granted authorities
*/
public Collection<GrantedAuthority> getAuthorities(Integer access) {
// Create a list of grants for this springUser
List<GrantedAuthority> authList = (List<GrantedAuthority>) new ArrayList<GrantedAuthority>(2);
// All users are granted with ROLE_USER access
// Therefore this springUser gets a ROLE_USER by default
System.out.println("Grant ROLE_USER to this user");
authList.add(new GrantedAuthorityImpl("ROLE_USER"));
// Check if this springUser has admin access
// We interpret Integer(1) as an admin springUser
// if ( access.compareTo(1) == 0) {
// // User has admin access
// logger.debug("Grant ROLE_ADMIN to this user");
// authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
// }
// Return list of granted authorities
return authList;
}
}
答案 0 :(得分:4)
默认情况下,Spring Security会在登录后将用户重定向到他最初请求的URL(在您的情况下为/
)。
您可以将always-use-default-target
设置为true
以禁用此行为:
<security:form-login
login-page="/login"
authentication-failure-url="/login?error=true"
default-target-url="/users/home"
always-use-default-target = "true"
/>