我正在编写一个Spring应用程序,该应用程序要求用户登录以访问使用Spring安全性保护的页面。当用户尝试访问安全页面时,系统会要求他们登录。如果登录成功,则应将用户直接重定向到安全页面,否则应重新显示登录页面并显示错误消息。目前不成功的方案有效,但如果用户确实正常登录,则仍会重新显示登录页面,尽管没有错误消息。
以下是相关的Java代码和Spring配置:
UserCredentialsController:
//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";
}
}
弹簧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";
}
答案 0 :(得分:0)
您需要将 default-target-url 属性添加到<form-login login-page="/login"/>
,该值将导致用户在成功登录后应该遇到的页面,如果省略(例如在您的情况下) )它导致应用程序的根目录。所以尝试像
<security:form-login login-page="/admin/login" default-target-url="/loginsuccess"
更新,要从服务进行身份验证,您可以尝试这样做
使用弹簧安全性注册自定义提供程序
<sec:authentication-manager alias="authenticationManager" erase-credentials="false">
<sec:authentication-provider ref="customAuthenticationProvider"/>
</sec:authentication-manager>
<bean id="customAuthenticationProvider" class="your.package.CustomAuthenticationProvider"/>
实施您的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;
}
}