gpt4 book ai didi

jsf spring security登录错误信息

转载 作者:行者123 更新时间:2023-12-01 19:44:37 25 4
gpt4 key购买 nike

我在 jsf2 Web 应用程序中使用 spring security 3。

如何在登录表单中显示错误的凭据消息,而不将 get param ?login_error 附加到authentiated-fail-login-page?

我尝试过使用相位监听器,如本教程所述:

http://tutorials.slackspace.de/tutorial/Custom-login-page-with-JSF-and-Spring-Security-3

但是这不起作用。

都没有使用 preRenderView 监听器。

也不检查 spring security 最后一个异常来呈现消息。

有什么想法吗?

更新:

我的登录页面:

<f:metadata>
<f:viewParam name="error" value="#{autenticacionController.error}" />
<f:event listener="#{autenticacionController.comprobarAuthException}" type="preRenderView" />
</f:metadata>
<h:messages globalOnly="true" layout="table" />
<h:form id="formLogin" prependId="false">
<h:outputLabel for="j_username" value="Usuario:" />
<h:inputText id="j_username" value="#{autenticacionController.administrador.login}" />
<h:outputLabel for="j_password" value="Contraseña:" />
<h:inputSecret id="j_password" value="#{autenticacionController.administrador.password}" />
<h:commandButton value="Entrar" action="#{autenticacionController.loginAction}" />
<h:commandButton value="Cancelar" immediate="true" action="#{autenticacionController.cancelarAction}" />
</h:form>

我的托管 bean:

@ManagedBean(name="autenticacionController")
@RequestScoped
public class AutenticacionController extends BaseController {

//entidad "administrador" contra el que validar los campos del form login
private Administrador administrador = new Administrador();

//propiedad de spring-security (true si el usuario no es anónimo)
@SuppressWarnings("unused")
private boolean autenticado;

//propiedad para guardar el param GET si hubo fallo en la autenticación de SS
private int error;

//Constructor vacío del Backing Bean controlador
public AutenticacionController() {
log.info("Creación del backing bean AutenticacionController");
}

@PostConstruct
public void init() {
//inicializar atributos del backing bean
log.info("PostConstruct del backing bean BarcoController");
}


//Getters y setters de atributos del backing bean
public Administrador getAdministrador() {
return administrador;
}
public void setAdministrador(Administrador administrador) {
this.administrador = administrador;
}

public boolean isAutenticado() {
Authentication autenticacion = SecurityContextHolder.getContext().getAuthentication();
boolean resultado = (autenticacion != null) &&
!(autenticacion instanceof AnonymousAuthenticationToken) &&
autenticacion.isAuthenticated();
return resultado;
}

public int getError() {
return error;
}
public void setError(int error) {
this.error = error;
}

//MÉTODO LISTENER del evento preRenderView en la página login.
//Para comprobar si la autenticación de Spring Security falló (error=1).
//En ese caso muestra el error con un faces message.
public void comprobarAuthException (ComponentSystemEvent event){
log.info("listener comprobarAuth");
if (error==1) {
String msj = "";
Exception e = (Exception) UtilJsf.getParamSessionMap(WebAttributes.AUTHENTICATION_EXCEPTION);
log.info("SSexception = "+((e==null)?"null":e.getMessage()));
if (e != null) {
String ultimoUsuario = (String) UtilJsf.getParamSessionMap(WebAttributes.LAST_USERNAME);
log.info("SS last_username = "+ultimoUsuario);
administrador.setLogin(ultimoUsuario);
if (e instanceof BadCredentialsException) {
msj = UtilJsf.getMsjProperties("msjsInfo", "UsuPwdIncorrectos");
} else {
msj = UtilJsf.getMsjProperties("msjsInfo", "ErrorAutenticacion");
}
UtilJsf.mostrarFacesMsjGlobal(msj);
}
}
return;
}


/* ******************************* */
/* Métodos "action" del form login */
/* ******************************* */

// EVENTO: Pulsar el botón "entrar" del form login
// Reenviar(FORWARD) la petición a la URL "/j_spring_security_check" para autenticarse
// También se debe configurar el filtro de spring-security para que procese forwards
public void loginAction () {
try {
FacesContext.getCurrentInstance().getExternalContext().dispatch("/j_spring_security_check");
} catch (IOException e) {
}
}

// EVENTO: Pulsar el boton "cancelar" en el form login
// No hacer nada --> Ir a la pantalla de inicio de la aplic
public String cancelarAction () {
return "/inicio";
}

}

在我的 Spring Security 配置中,我有:

authentication-failure-url="/faces/paginas/autenticacion/login.xhtml?error=1"

如果我从登录页面删除错误参数和 viewParam,并且在监听器中仅检查 Spring Security 异常,则它不起作用。

感谢您注销,我的方法类似,我有以下链接:

<h:outputLink value="#{request.contextPath}/j_spring_security_logout" rendered="#{autenticacionController.autenticado}">Cerrar sesión (Administrador)</h:outputLink>

最佳答案

我倾向于使用<f:event>在 preRenderView 上,它将更新我表单上的消息组件。我就是这样做的。

<f:event listener="#{loginBean.updateMessages(true)}" type="preRenderView" />
<div style="margin-left: 50px; width: 500px;"><br />
<h:form id="loginForm" prependId="false">

<p:messages id="errorMessages" />
<label for="j_username">
<h:outputText value="Username:" /><br />
</label>
<h:inputText id="j_username" required="true" width="500" style="width: 300px;" />

<br />
<br />
<label for="j_password">
<h:outputText value="Password:" /><br />
</label>
<h:inputSecret id="j_password" required="true" width="500" style="width: 300px;" />
&nbsp;<h:link value="Forgot my password" outcome="forgotpassword" />
<br />
<br />
<label for="_spring_security_remember_me">
<h:outputText value="Remember me" />
</label>
<h:selectBooleanCheckbox id="_spring_security_remember_me" />
<br /><br />
<p:commandButton ajax="false" type="submit" id="login" action="#{loginBean.doLogin}" value="Login" update="errorMessages" />
</h:form>
</div>

然后在我的 LoginBean 托管 bean 中,我将请求转发到 Spring Security servlet,并更新消息。如果您有兴趣了解我如何解决该问题,您会注意到我还有注销操作的代码。

private String username;
private String password;

public String getUsername() {
return username;
}

public void setUsername(final String username) {
this.username = username.trim();
}

public String getPassword() {
return password;
}

public void setPassword(final String password) {
this.password = password.trim();
}

public void updateMessages(boolean update) throws Exception {
System.out.println("Start LoginBean.updateMessages");
ex = (Exception)FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.get(WebAttributes.AUTHENTICATION_EXCEPTION);

if (ex != null) {
log.error("Authentication Failed! ", ex);
System.err.println("Authentication Failed! " + ex.getMessage());
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ex.getMessage()));
}
System.out.println("End LoginBean.updateMessages");
}

public String doLogin() {
log.info("Start LoginBean.doLogin");
try {
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();

RequestDispatcher dispatcher = ((ServletRequest) context.getRequest())
.getRequestDispatcher("/j_spring_security_check");

dispatcher.forward((ServletRequest) context.getRequest(),
(ServletResponse) context.getResponse());

FacesContext.getCurrentInstance().responseComplete();
// It's OK to return null here because Faces is just going to exit.
} catch (Exception e) {
log.error("Exception doLogin", e);
} finally {
log.info("End LoginBean.doLogin");
}
return "";
}

public String logout() {
FacesContext context = FacesContext.getCurrentInstance();
Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
if (!sessionMap.containsKey("sessionBean"))
return "";

SessionBean sessionBean = (SessionBean)sessionMap.get("sessionBean");
log.info("Logging out user: " + sessionBean.getLoggedInUser().getUsername());

sessionMap.remove("sessionBean");

//HttpSession session = (HttpSession)context.getExternalContext().getSession(false);
//session.invalidate();
RequestDispatcher dispatcher = ((ServletRequest) context.getExternalContext().getRequest())
.getRequestDispatcher("/j_spring_security_logout");

try {
dispatcher.forward((ServletRequest) context.getExternalContext().getRequest(),
(ServletResponse) context.getExternalContext().getResponse());
} catch (ServletException e) {
log.error("ServletException", e);
} catch (IOException e) {
log.error("IOException", e);
}

FacesContext.getCurrentInstance().responseComplete();
// It's OK to return null here because Faces is just going to exit.

log.info("End LoginBean.logout");
return "";
}

public boolean isLoggedIn() {
FacesContext context = FacesContext.getCurrentInstance();
Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
return sessionMap.containsKey("sessionBean");
}

编辑:

我想我现在更好地理解你的问题了。我记得我也很难让它工作,所以基本上我必须编写自己的类来实现 AuthenticationFailureHandler并正确实现该方法:

@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException ex) throws IOException, ServletException {
//Do business logic stuff, logging, etc...
request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, ex);
response.sendRedirect("login.xhtml");

基本上,您会看到我正在实例化一个异常并将其设置为 session 属性,以便稍后在我的托管 bean 中可以检索它并将其转换为 FacesMessage .

您还必须声明此 AuthenticationFailureHandler作为 Spring Security 配置文件中身份验证失败事件的自定义处理程序(请注意,我还展示了我对身份验证成功处理程序执行相同的操作,但您可能也不想这样做).

<form-login login-page="/login.xhtml" login-processing-url="/j_spring_security_check"
authentication-success-handler-ref="authenticationSuccessBean"
authentication-failure-handler-ref="authenticationFailureBean" />

...
<beans:bean id="authenticationFailureBean" class="com.maple.controllers.FailureHandler">
<beans:property name="userBo" ref="userController" /> <!-- Just injecting my BL layer... -->
</beans:bean>

关于jsf spring security登录错误信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8919103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com