Java 登录后spring security的重定向不正确

Java 登录后spring security的重定向不正确,java,spring,jakarta-ee,spring-mvc,spring-security,Java,Spring,Jakarta Ee,Spring Mvc,Spring Security,编辑-- 我猜最初的url请求是“/”,所以在成功登录时,用户登陆到“/” 如果用户在登录前已输入site.com/someOtherUrl,则在登录成功后将登录到site.com/someOtherUrl。如何解决这个问题/ 编辑结束-- 对于mysite.com或localhosr:8080当用户到来时 他登陆到/login页面,然后输入凭证并按下登录按钮 现在他实际上已经登录了。他应该降落在/users/home 但他降落在/ 此时,当他登录时,他可以使用地址栏手动转到/users/hom

编辑--

我猜最初的url请求是“/”,所以在成功登录时,用户登陆到“/”

如果用户在登录前已输入site.com/someOtherUrl,则在登录成功后将登录到site.com/someOtherUrl。如何解决这个问题/

编辑结束--

对于
mysite.com
localhosr:8080
当用户到来时

他登陆到
/login
页面,然后输入凭证并按下登录按钮

现在他实际上已经登录了。他应该降落在
/users/home

但他降落在
/

此时,当他登录时,他可以使用地址栏手动转到
/users/home

一个不知情的用户(关于这个问题)会按后退按钮再次登录,然后按他应该的方式登录到正确的url
/users/home
页面

问题是,为什么不是第一次?为什么他在第一次登录时登录到“/”而不是/users/home

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

login.jsp
org.springframework.web.context.ContextLoaderListener
springDispatcher
org.springframework.web.servlet.DispatcherServlet
1.
springDispatcher
/
30
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
上下文配置位置
/WEB-INF/spring-security.xml
/WEB-INF/applicationContext.xml
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;
   }

}
包web.service.common;
导入java.util.ArrayList;
导入java.util.Collection;
导入java.util.List;
导入javax.annotation.Resource;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.dao.DataAccessException;
导入org.springframework.security.core.GrantedAuthority;
导入org.springframework.security.core.userdetails.User;
导入org.springframework.security.core.userdetails.userdetails;
导入org.springframework.security.core.userdetails.userdetails服务;
导入org.springframework.security.core.userdetails.UsernameNotFoundException;
导入org.springframework.stereotype.Repository;
导入org.springframework.stereotype.Service;
导入web.dao.UsersDAO;
导入web.dao.impl.jpa.UsersDAOImpl;
导入web.entity.Users;
@服务
公共类CustomUserDetailsService实现UserDetailsService{
//@资源
@自动连线
私有用户dao userDAO;
/**
*检索包含springUser凭据和访问权限的springUser记录。
*/
公共用户详细信息loadUserByUsername(字符串电子邮件)
抛出UsernameNotFoundException、DataAccessException{
//声明一个空的Spring用户
UserDetails-springUser=null;
试一试{
System.out.println(“方法loadUserByUsername中从CustomUserDetailsService传递的电子邮件为:“+email”);
//在数据库中搜索与指定电子邮件匹配的springUser
//您可以提供一个自定义DAO来访问持久层
//或者使用JDBC访问您的数据库
//DbUser是我们的自定义域springUser。这与Spring的用户不同
System.out.println(“debug---1”);
Users dbUser=userDAO.getUserByLoginId(电子邮件);
//使用dbUser中的详细信息填充Spring用户对象
//这里我们只传递电子邮件、密码和访问级别
//getAuthories()将访问级别转换为正确的角色类型
System.out.println(“debug---2”);
springUser=新用户(
dbUser.getEmail(),
dbUser.getPassword().toLowerCase(),
符合事实的
符合事实的
符合事实的
符合事实的
//getAuthories(dbUser.getAccess());
(二),;
System.out.println(“debug---3”);
}捕获(例外e){
System.out.println(“检索用户时出现打印错误”);
e、 printStackTrace();
System.out.println(e.getMessage());
抛出新的UsernameNotFoundException(“检索用户时出错”);
}
System.out.println(“debug---4”);
//将springUser返回到Spring进行处理。
//请注意,我们不是评估此springUser是否经过身份验证或有效的人
//我们只需检索与指定电子邮件匹配的springUser
返回用户;
}
/**
*根据访问级别检索正确的角色类型,其中访问级别为整数。
*基本上,无论是普通springUser还是admin,这都会解释访问值。
*
*@param access表示springUser访问权限的整数值
*@已授予权限的返回集合
*/
公共集合权限(整数访问){
//为此springUser创建授权列表
List authList=(List)新数组列表(2);
//所有用户都被授予角色\用户访问权限
//因此,默认情况下,此springUser获得一个角色\用户
System.out.println(“将角色_用户授予此用户”);
add(新授予的authorityImpl(“角色用户”);
//检查此springUser是否具有管理员权限
//我们将整数(1)解释为管理员用户
//if(访问比较到(1)==0){
////用户具有管理员权限
//debug(“向该用户授予角色_ADMIN”);
//add(新授予的authorityImpl(“角色\管理员”);
//   }
//已授予权限的返回列表
返回authList;
}
}

默认情况下,Spring Security会在用户登录后将用户重定向到他最初请求的URL(在您的情况下为
/

您可以将
始终使用默认目标设置为
true
以禁用此行为:

<security:form-login
    login-page="/login"
    authentication-failure-url="/login?error=true"
    default-target-url="/users/home"
    always-use-default-target = "true"
/>

默认情况下,弹簧安全红色