# Spring Security 3 und JSF 2.0



## Dimarzio (22. Nov 2010)

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!


----------



## pherin (12. Dez 2010)

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.

```
<?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"

```
<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: 

```
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.

```
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.


----------



## Dimarzio (13. Dez 2010)

pherin hat gesagt.:


> Hi,
> 
> mein Problem war, dass ich nicht hinbekommen konnte, dass die Dinge miteinander funktionieren. Ich habe mittlerweile schon einen Faden gefunden, aber ich das zeitlich ein bisschen zurückgestellt. Ich werde mich damit vielleicht in den nächsten Wochen beschäftigen.
> 
> Deine Antwort merke ich mir trotzdem  Danke.


----------



## KrustyDerClown (17. Dez 2010)

Welchen "Faden" hast du gefunden? Vielleicht für andere auch noch interessant ...


----------



## Dimarzio (19. Dez 2010)

KrustyDerClown hat gesagt.:


> Welchen "Faden" hast du gefunden? Vielleicht für andere auch noch interessant ...



Guter Punkt! Immer denke ich nur an mich selbst...

Over the Edge: JSF 2.0 with Spring 3 and Spring Security 3 on Google Application Engine

Hier liegt alles offen... Ist zwar relativ umfangreich, aber die meisten Sachen kann man eh weg schmeißen.


----------



## Kian (25. Okt 2012)

pherin hat gesagt.:


> Du kannst jedoch auch eine Methode in einer ManagedBean definieren, die den Login erledigt. Wie bereits erwähnt hatte ich dabei aber einige Probleme.
> 
> ```
> public String login(AuthenticationManager authenticationManager) {
> ...



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


----------

