Spring Security 3 und JSF 2.0

Dimarzio

Mitglied
Hallo zusammen,

ich stehe im Moment vor einem Problem. Irgendwie bekomme ich schon seit Tagen nicht hin JSF 2.0 und Spring Security 3 zu verheiraten...

Könnte mir jemand evtl. ein aktuelles Tutorial empfeheln bzw. eigenes Beispiel zeigen?

Das einzige was ich brauche ist lediglich eine Benutzerauthentifizierung. Login/Passwort. Das wird dann im security-context gepflegt. Irgendwie ist mir einfach nicht klar, was ich alles dafür brauche.

AppServer muss/kann glassfish sein und bei JSF ist es die mojarra implementierung.

Alternativ würde ich mich auch über ähnliches mit Apache Shiro freuen 🙂

Für jeden Tipp wäre ich sehr dankbar!
 
Könntest du etwas genauer erklären, was genau nicht funktioniert?

Anbei Teile meiner Security-Konfiguration. In meinem Fall verwende ich einen UserDetailsManager, der die Benutzerdaten per Hibernate aus der Datenbank holt.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">

	<authentication-manager alias="authenticationManager">
		<authentication-provider user-service-ref="userDetailsManager">
				<password-encoder hash="md5" />
		</authentication-provider>
	</authentication-manager>
	<beans:bean id="userDetailsManager" class="x.y.z.UserDetailsManager" />
 	
 	<beans:bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
 		<beans:property name="errorPage" value="/accessDenied.xhtml"/>
 	</beans:bean>
 	
	<http use-expressions="true" >
		<http-basic />
		<logout />
		<access-denied-handler ref="accessDeniedHandler"/>

		<form-login login-page="/spring/admin/login.xhtml" default-target-url="/spring/admin/index.xhtml" />

		<session-management invalid-session-url="/spring/admin/login.xhtml">
			<concurrency-control max-sessions="1" expired-url="/" error-if-maximum-exceeded="true" />
		</session-management>
		
		<intercept-url pattern="/**" access="permitAll" />
		<intercept-url pattern="/spring/public/**" access="permitAll"/>
		
		<intercept-url pattern="/spring/admin/login.xhtml" access="permitAll" />
		<intercept-url pattern="/spring/admin/**" access="hasAnyRole('ROLE_STAFF', 'ROLE_ADMIN')" />
	</http>
</beans:beans>

Die Login-Seite habe ich, nachdem ich einige Probleme mit dem Logout hatte, wenn ich mich über eine JSF-action-methode angemeldet habe, auf ein standard-html formular umgebaut. Eingebettet ist das in einer xhtml-Datei.

"login.xhtml"
Code:
<form action="#{request.contextPath}/j_spring_security_check" method="post">
	Benutzername: <input type="text" name="j_username" /><br/>
	Passwort: <input type="password" name="j_password" /><br/>
	<input type="submit" value="Anmelden" />
</form>

Wenn dein Login erfolgreich war, wirst du auf die default-target-url umgeleitet ("/spring/admin/index.xhtml").


Für einen Logout musst du dann nur einen Link wie folgt setzen:
Code:
Entweder:
<a href="#{request.contextPath}/j_spring_security_logout">Abmelden</a>
Oder:
<h:outputLink value="#{request.contextPath}/j_spring_security_logout}">Abmelden</h:outputLink>


Du kannst jedoch auch eine Methode in einer ManagedBean definieren, die den Login erledigt. Wie bereits erwähnt hatte ich dabei aber einige Probleme.
Java:
public String login(AuthenticationManager authenticationManager) {
	try {
		logger.info("Trying to log in: " + m_username);
		if (m_username == null || m_password == null) {
			FacesMessage facesMsg = new FacesMessage(
			FacesMessage.SEVERITY_ERROR, "Error", messageDAO.getMessage("login.failed") );
			FacesContext.getCurrentInstance().addMessage(null, facesMsg);
			return "error";
		}
		Authentication request = new UsernamePasswordAuthenticationToken(
					m_username, m_password);			
			
		Authentication result = authenticationManager.authenticate(request);
		SecurityContextHolder.getContext().setAuthentication(result);

	} catch (AuthenticationException e) {

		FacesMessage facesMsg = new FacesMessage(
			FacesMessage.SEVERITY_ERROR, "Error", messageDAO.getMessage("login.failed") );
		FacesContext.getCurrentInstance().addMessage(null, facesMsg);
			
		return "error";
	}
	return "success";
}

m_username und m_password sind dabei die properties, die du auf deiner JSF-Seite für die <h:inputText> Felder verwendest.
 
Zuletzt bearbeitet:
Du kannst jedoch auch eine Methode in einer ManagedBean definieren, die den Login erledigt. Wie bereits erwähnt hatte ich dabei aber einige Probleme.
Java:
public String login(AuthenticationManager authenticationManager) {
	try {
		logger.info("Trying to log in: " + m_username);
		if (m_username == null || m_password == null) {
			FacesMessage facesMsg = new FacesMessage(
			FacesMessage.SEVERITY_ERROR, "Error", messageDAO.getMessage("login.failed") );
			FacesContext.getCurrentInstance().addMessage(null, facesMsg);
			return "error";
		}
		Authentication request = new UsernamePasswordAuthenticationToken(
					m_username, m_password);			
			
		Authentication result = authenticationManager.authenticate(request);
		SecurityContextHolder.getContext().setAuthentication(result);

	} catch (AuthenticationException e) {

		FacesMessage facesMsg = new FacesMessage(
			FacesMessage.SEVERITY_ERROR, "Error", messageDAO.getMessage("login.failed") );
		FacesContext.getCurrentInstance().addMessage(null, facesMsg);
			
		return "error";
	}
	return "success";
}

m_username und m_password sind dabei die properties, die du auf deiner JSF-Seite für die <h:inputText> Felder verwendest.

Hallo,
wie macht man das mit einem persistent Token Remember-Me?
Danke.
 

Zurück
Oben