And*_*daP 3 jsf spring spring-security jsf-2
我有一个使用JSF的Web应用程序,Spring安全性用于登录和授权.
当用户键入特定页面并且他没有登录时,例如localhost:8080/APP/page.xhtml,应用程序重定向到登录页面即可.之后,用户已登录,但他被重定向到的页面index.xhtml是默认的欢迎页面,而不是page.xhtml.
我想要以下行为:用户去localhost:8080/APP/page.xhtml,他被重定向到登录,之后他应该被重定向到他想要的页面 - page.xhtml.
已编辑 - spring-security.xml的片段:
<security:http auto-config="true">
<security:intercept-url pattern="/javax.faces.resource/*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:intercept-url pattern="/login.xhtml" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:intercept-url pattern="/**" access="ROLE_UNALLOCATED, ROLE_MANAGER"/>
<security:intercept-url pattern="/pages/management/" access="ROLE_MANAGER"/>
<security:intercept-url pattern="/pages/requests/" access="ROLE_UNALLOCATED, ROLE_EMPLOYEE, ROLE_TEAM_LEADER, ROLE_MANAGER"/>
<security:form-login login-page="/login.xhtml"
/>
<security:logout logout-url="/j_spring_security_logout"
logout-success-url="/login.xhtml"
invalidate-session="true"/>
</security:http>
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?谢谢
编辑:
我以为是因为:
<!-- Welcome page -->
<welcome-file-list>
<welcome-file>/index.xhtml</welcome-file>
</welcome-file-list>
Run Code Online (Sandbox Code Playgroud)
来自web.xml.我删除了这个,但结果相同.
稍后编辑:
我刚注意到我的自定义loginController中的一行,之后if (authenticationResponseToken.isAuthenticated())几乎肯定是问题的根源:
loginController:
@ManagedBean(name = "loginController")
@SessionScoped
@Controller
public class LoginController implements Serializable {
private static final long serialVersionUID = 1L;
@Autowired
IUserService userService;
@Autowired
@Qualifier("authenticationManager")
protected AuthenticationManager authenticationManager;
// save the current user after login to be able to inject it in other places
// as needed
private User currentUser;
/**
* This action logs the user in and returns to the secure area.
*
* @return String path to secure area
*/
public String loginUsingSpringAuthenticationManager() {
// get backing bean for simple redirect form
LoginFormBackingBean loginFormBean = (LoginFormBackingBean) FacesUtils
.getBackingBean("loginFormBean");
// simple token holder
Authentication authenticationRequestToken = createAuthenticationToken(loginFormBean);
// authentication action
try {
Authentication authenticationResponseToken = authenticationManager
.authenticate(authenticationRequestToken);
Authentication authCopy = null;
final Object principal = authenticationResponseToken.getPrincipal();
if (principal instanceof LdapUserDetailsImpl) {
LdapUserDetailsImpl userImpl = (LdapUserDetailsImpl) principal;
userImpl.getUsername();
// here check if we already have a User with his DN in the DB
// get the User by DN
User u = userService.getUserByDn(userImpl.getDn());
// if a user with this DN does not exist in the DB, create a new
// one with the DN from LDAP and the default settings for a new
// user
if (null == u) {
u = userService.createNewUserFromDn(userImpl.getDn(),
userImpl.getUsername());
}
// set the obtained user as the current user
setCurrentUser(u);
List<GrantedAuthority> grAuth = new ArrayList<GrantedAuthority>();
// after this, do the role authority stuff
// here loop through user roles if he has more and
if (null != u.getUserTeamRoles()) {
for (UserTeamRole urt : u.getUserTeamRoles()) {
// here get role for every UserTeamRole
grAuth.add(new SimpleGrantedAuthority(urt.getRole()
.getName()));
}
}
// add the above found roles to the granted authorities of the
// current authentication
authCopy = new UsernamePasswordAuthenticationToken(
authenticationResponseToken.getPrincipal(),
authenticationResponseToken.getCredentials(), grAuth);
}
SecurityContextHolder.getContext().setAuthentication(authCopy);
// ok, test if authenticated, if yes reroute
if (authenticationResponseToken.isAuthenticated()) {
// lookup authentication success url, or find redirect parameter
// from login bean
return "index.xhtml?faces-redirect=true";
}
} catch (BadCredentialsException badCredentialsException) {
// FacesMessage facesMessage = new FacesMessage(
// "Login Failed: please check your username/password and try again.");
// FacesContext.getCurrentInstance().addMessage(null, facesMessage);
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(FacesMessage.SEVERITY_ERROR,
"Sample error message",
"Login Failed! Please check your credentials"));
} catch (LockedException lockedException) {
FacesMessage facesMessage = new FacesMessage(
"Account Locked: please contact your administrator.");
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
} catch (DisabledException disabledException) {
FacesMessage facesMessage = new FacesMessage(
"Account Disabled: please contact your administrator.");
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
}
return null;
}
private Authentication createAuthenticationToken(
LoginFormBackingBean loginFormBean) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
loginFormBean.getUserName(), loginFormBean.getPassword());
return usernamePasswordAuthenticationToken;
}
Run Code Online (Sandbox Code Playgroud)
如何重定向到我需要的页面?我有一个包含用户和密码的loginBean,我可以添加一个redirectUrl但是如何找到以前的url路径?
Spring Security 通过使用SavedRequestAwareAuthenticationSuccessHandler(它使用了隐藏的HttpSessionRequestCache )在AbstractAuthenticationProcessingFilter中实现了这个逻辑(通常使用UsernamePasswordAuthenticationFilter的具体实现).由于您已编写了一个要进行身份验证的控制器(而不是使用内置支持),因此您需要自己实现此逻辑.您可以重用Spring Security所使用的相同类,而不是自己实现所有逻辑.
例如,您的LoginController可能会更新如下:
public class LoginController implements Serializable {
// ... same as before ...
private RequestCache requestCache = new HttpSessionRequestCache();
public String loginUsingSpringAuthenticationManager() {
// ... just as you had been doing ...
if (authenticationResponseToken.isAuthenticated()) {
HttpServletRequest request = (HttpServletRequest)
FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse)
FacesContext.getCurrentInstance().getExternalContext().getResponse();
SavedRequest savedRequest = requestCache.getRequest(request, response);
return savedRequest.getRedirectUrl();
}
// ... same as you had ...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10874 次 |
| 最近记录: |