如何使用spring security验证bean内的登录?

时间:2012-11-20 20:12:40

标签: jsf-2 spring-security

所以我正在学习Spring,而我正在使用PrimeFaces的JSF。

我的问题:

我想知道如何(如果可能的话)使用bean中的布尔函数来验证和授权用户凭证,如下所示:

public boolean check() {
  boolean isLoginValid = false;
  if (//run something like j_spring_security_check) {
      //obtain user authorizations....
      isLoginValid = true;
  }
  return isLoginValid;
}

原因:

public void doLogin() {
    RequestContext context = RequestContext.getCurrentInstance();

    FacesMessage msg;
    boolean loggedIn;

    if (check() //would use the functin here) {
        loggedIn = true;
        msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome", usuario);
    } else {
        loggedIn = false;
        msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Login Error", "Invalid credentials");
    }

    FacesContext.getCurrentInstance().addMessage(null, msg);
    context.addCallbackParam("loggedIn", loggedIn);
    context.addCallbackParam("authorization", this.auth #obtained in check());
}

这样我可以通过ajax将布尔值发送到我的按钮,如下所示:

<p:commandButton id="loginButton" value="Login" update=":growl"   
                          actionListener="#{loginBean.doLogin}"   
                          oncomplete="handleLoginRequest(xhr, status, args)"/>

function handleLoginRequest(xhr, status, args) {
            if(args.validationFailed || !args.loggedIn) {  
                jQuery('#dialog').effect("shake", { times:3 }, 100);
            } else {
                jQuery('#dialog').effect("shake", { times:1 }, 200);
                //And redirect to the right page.
            }  
        }

谢谢!

1 个答案:

答案 0 :(得分:0)

SpringBeanFacesELResolver的帮助下,您可以从Spring Application Context中解析托管属性Authentication Manager,并且JSF的IOC将bean注入您的支持bean。

为此,将SpringBeanFacesELResolver添加到faces-config.xml中,如下所示:

<application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

然后在您的支持bean中,您可以验证传递的Authentication对象,如下所示:

public class LoginBean implements Serializable {
    private static final long serialVersionUID = 1L;
    private String userName;
    private String password;
    @ManagedProperty(value="#{authenticationManager}")
        private AuthenticationManager authenticationManager;
        public AuthenticationManager getAuthenticationManager() {
        return authenticationManager;
    }

    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        this.authenticationManager= authenticationManager;
    }

    public String doLogin() {
        Authentication authenticationRequestToken =
              new UsernamePasswordAuthenticationToken( userName, password );
        //authentication action
        try {
            Authentication authenticationResponseToken =
                authenticationManager.authenticate(authenticationRequestToken);
            SecurityContextHolder.getContext().setAuthentication(authenticationResponseToken);
            //ok, test if authenticated, if yes reroute
            if (authenticationResponseToken.isAuthenticated()) {
                //lookup authentication success url, or find redirect parameter from login bean
                return "/secure/examples";
            }
        } catch (BadCredentialsException badCredentialsException) {
            FacesMessage facesMessage =
                new FacesMessage("Login Failed: please check your username/password and try again.");
            FacesContext.getCurrentInstance().addMessage(null,facesMessage);
        } 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;
    }
}

另见:

<强>更新

如果由于某种原因无法使用@ManagedProperty。您可以尝试使用Spring @Autowired注释,将JSF ManagedBean转换为Spring管理的Component。 为此注释bean如下:

@Component
@Scope("request")
public class LoginController implements Serializable {
    @Autowired
    private AuthenticationManager authenticationManager;
        //bean getters and setters

并将component-scan元素添加到Spring Application上下文中:

<context:component-scan base-package="com.examples"/>

关于使用authentication-success-handler-ref的问题,我担心你可以使用它,因为我们手动进行身份验证。如果您的要求是根据用户角色转发到适当的URL。你可以这样做:

if (authenticationResponseToken.isAuthenticated()) {
   String userTargetUrl = "/general/main";
   String adminTargetUrl = "/secure/examples";
   Set<String> roles = AuthorityUtils.authorityListToSet(authenticationResponseToken.getAuthorities());
   if (roles.contains("ROLE_ADMIN")) {
      return adminTargetUrl;
   }
   else if(roles.contains("ROLE_USER")) {
      return userTargetUrl;
   }
}