【问题标题】:Spring cannot redirect to secure pageSpring 无法重定向到安全页面
【发布时间】:2015-01-16 20:48:21
【问题描述】:

我正在编写一个 Spring 应用程序,该应用程序要求用户登录才能访问已使用 Spring 安全性保护的页面。当用户尝试访问安全页面时,他们会被要求登录。如果登录成功,用户应该被直接重定向到安全页面,否则登录页面应该重新显示错误消息。目前不成功的场景有效,但如果用户正确登录,登录页面仍然会重新显示,尽管没有错误消息。

这里是相关的Java代码和Spring配置:

用户凭据控制器:

//Methods omitted above.


@RequestMapping(value="/login", method = RequestMethod.GET)
public String login(Model model){
    System.out.println("In login() method");
    model.addAttribute("credentials", new User());
    return "login";
}
@RequestMapping(value="/checkcredentials", method = RequestMethod.POST)
public String checkCredentials(@ModelAttribute ("credentials") User user, Model model, HttpServletResponse response){
    if(userService.getUser(user)){
       //I am trying to redirect the user here in the event of a successful log in. Does not work at present. 
        return "redirect:/addincident"; 

        }
        else{
         model.addAttribute("message", "Username and/or password is/are not valid");
            //This works at the moment.
            return "login";
        }
}

spring-security.xml:

<beans:beans xmlns="http://www.springframework.org/schema/security"
       xmlns:beans="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.2.xsd">


 <http auto-config="true">
     <intercept-url pattern="/addincident" access="ROLE_USER, ROLE_ADMIN"/>
     <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
     <form-login login-page="/login"/>
 </http>

<authentication-manager>
  <authentication-provider>
      <user-service>
            <user name="daj" password="123" authorities="ROLE_USER, ROLE_ADMIN" />
            <user name="eoj" password="123" authorities="ROLE_USER" />
      </user-service>
  </authentication-provider>
</authentication-manager>

我目前的想法是这是一个安全问题。这是因为以前我使用 Spring 的默认登录页面,当我使用基于 XML 的用户时它工作得很好。但是现在我将用户保存在数据库中,并且我有自己的登录页面,并且导航不再按我期望的方式工作。

编辑:这是 addIncident 方法。当我使用默认的 Spring 登录表单时,它会正确加载。

GeneralIncidentController:

//Methods omitted above.
@RequestMapping(value = "/addincident", method = RequestMethod.GET)
public String addIncident(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model){
    model.addAttribute("message", "Spring 3 MVC Hello World");
    model.addAttribute("name", name);
    model.addAttribute("details", new GeneralIncident());      //Need this to populate bean with submitted data for validation.
    return "myform";
}

【问题讨论】:

  • 我不确定这是否适用于我的情况?看起来该配置用于使用默认登录页面。我有名为 authentication-manager 的标签,但没有 bean。

标签: java spring security spring-mvc spring-security


【解决方案1】:

您需要为&lt;form-login login-page="/login"/&gt; 添加一个 default-target-url 属性,该值将指向用户成功登录后应该遇到的页面,如果省略(如您的情况)它通向应用程序的根目录。所以尝试类似

<security:form-login login-page="/admin/login" default-target-url="/loginsuccess"

更新,要从服务进行身份验证,您可以这样尝试

  1. 向 Spring Security 注册您的自定义提供程序

    <sec:authentication-manager alias="authenticationManager" erase-credentials="false">
      <sec:authentication-provider ref="customAuthenticationProvider"/>
    </sec:authentication-manager>
    <bean id="customAuthenticationProvider" class="your.package.CustomAuthenticationProvider"/>
    
  2. 实现您的 CustomProvider

    public class CustomAuthenticationProvider implements AuthenticationProvider {
    
    @Autowired
    private YourUserService userService;
    
    
    @Override
    public boolean supports(Class<? extends Object> authentication) {
        return (authentication.equals(UsernamePasswordAuthenticationToken.class) || authentication.equals(UrlAuthenticationToken.class));
    }
    
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationServiceException {
        YourUser user = userService.loginByEmailAndPassword((String) authentication.getPrincipal(), (String) authentication.getCredentials());
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        Authentication endUserAuth = new UsernamePasswordAuthenticationToken(user, user.getPassword(), grantedAuthorities);
        return endUserAuth;
    }
    

    }

【讨论】:

  • 我刚刚尝试过这个(尽管我的值略有不同以反映我的应用程序),但我仍然遇到同样的问题。您还需要其他代码/配置信息吗?
  • 您可以发布映射到 /addincident 的方法。另外,我不确定特异性规则是否也适用于表单登录,但请务必将表单登录元素推为列表中的第一个,然后从最具体的向下列出拦截
  • 发布了方法并移动了 form-login 元素,但它仍然不起作用。
  • 事实上,对于弹簧安全性而言,一切似乎都是正确的。我只在您登陆登录页面时回答了帐户,再次阅读时您提到您在尝试不安全页面时遇到问题。我正在考虑删除我的回复。您也可以发布您的身份验证管理器,也许有一些东西
  • 添加了authentication-manager 标签。请注意,如果我尝试使用这些凭据登录,它将无法在自定义登录页面上运行,但它可以在默认页面上运行。
猜你喜欢
  • 2014-01-23
  • 1970-01-01
  • 2014-02-06
  • 2014-04-14
  • 1970-01-01
  • 2016-06-05
  • 2020-06-19
  • 1970-01-01
  • 2013-01-05
相关资源
最近更新 更多