# Spring Security



## MQue (11. Jan 2010)

Hallo,

ich verwende in meiner Web Applikation Spring Security und es klappt auch einwandfrei, Jetzt möchte ich aber einen Eintrag in eine Datenbank schreiben, sobald jemand eingelogged hat, 
Ich hab Spring Security so configuriert, wie hier angegeben, also ganz einfach: 7.The Security Filter Chain

Das http Element habe ich so konfiguriert wie hier angegeben: 2.Security Namespace Configuration

Es macht beim einloggen also alles Spring, vom Bereitstellen der login-Page bis zum Weiterleiten auf die default- page nach dem erfolgreichen login.

Meine Frage wäre jetzt, wie kann ich in diesem lifecycle eingreifen, sodass nach dem erfolgreichen Login eine Methode aufgeerufen wird, in der ich dann username in die Datenbank schreiben kann.

Hat da jemand eine Idee?
lg


----------



## MQue (12. Jan 2010)

Ich habe eine Möglichkeit gefunden, mein Problem ist, dass ich in meiner Applikation Spring 2.0.5 verwende und Spring3.0 die Möglichkeit bietet, 
Kann man die verschiedenen Spring- Versionen mischen, also ausser Spring Security (3.0) alles 2.0 oder ist das keine so gute Idee?
lg


----------



## MQue (12. Jan 2010)

Ganz ist es mir nicht klar, einen Eintrag in die DB oder in ein File zu schreiben, wenn sich jemand einlogged, ist ja keine spezielle Sache, trotzdem find ich kaum bis nichts dazu. Es gibt zwar ein paar Provider (DaoAuthenticationProvider, RemoteAuthenticationProvider, usw.), aber die sind dazu da, den usernamen und das password an verschiedenen Orten zu suchen. Ich bräuchte aber eine Methode, die nach der Überprüfung von username und password durch den authentication-provider (unten) aufgerufen wird!!??



```
<authentication-provider>                                                                                      
                <user-service>
                    <user name="test" password="testpassword" authorities="ROLE_USER, ROLE_ADMIN, ROLE_TELLER" />           
                    <user name="test1" password="test1password" authorities="ROLE_USER" />
                </user-service>
            </authentication-provider>
```


----------



## Noctarius (12. Jan 2010)

Acegi - Method based Security für Spring sowas?


----------



## MQue (13. Jan 2010)

Hab mirs angesehen, aber da gehts eher um das, ob ein Benutzer eine Methode aufrufen darf oder nicht, so weit ich das jetzt überblicken konnte, ich bräuchte aber nach dem erfolgreichen einloggen eine Methode, in welcher ich username in eine Datei/DB schreiben kann.
Ich habe jetzt auch schon im Spring- Forum die Frage gestellt, es gibt aber anscheinend keine einfache Antwort, was ich irgendwie komisch finde, denn Login loggen ist ja nicht unbedingt was, das man nie braucht, oder sehe ich das falsch?

lg


----------



## byte (13. Jan 2010)

Du hast doch sicherlich irgendwo Deinen eigenen UserDetailsService implementiert. Du kannst das doch einfach in der loadUserByUsername() Methode implementieren!?

Edit: Ansonsten kannst Du Dir auch jederzeit den aktuellen User aus dem SecurityContext holen. Du könntest also einfach einen Interceptor hinter Deinen Controller hängen, der den User ausliest und loggt (bin mal davon ausgegangen, dass Du Spring MVC nutzt).


----------



## MQue (13. Jan 2010)

byte hat gesagt.:


> (bin mal davon ausgegangen, dass Du Spring MVC nutzt).



Leider nicht, es wird ein normales Servlet für die ClientCommunication verwendet, dieses Servlet ruft dann Services auf, die dann was in die Datenbank speichern.
Architektur ist nicht von mir, mir ist klar, dass mans so nicht macht aber es ist leider schon so vorhanden. Gibt es hier vielleicht noch eine andere Lösung?

Besten Dank,


das ist die SpringSecurity.xml

```
<global-method-security secured-annotations="enabled" jsr250-annotations="enabled"/>                        
            <http auto-config='true'>                                                                                       
                <intercept-url pattern='/index.jsp' access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https" />
                <intercept-url pattern='/**' access='ROLE_USER' requires-channel="https" />
                <form-login login-page='/index.jsp' default-target-url='/frame.jsp' always-use-default-target='true' />    
            </http>
            <authentication-provider>                                                                                       
                <user-service>
                    <user name="test" password="testpassword" authorities="ROLE_USER, ROLE_ADMIN, ROLE_TELLER" />          
                    <user name="test1" password="test1password" authorities="ROLE_USER" />
                </user-service>
            </authentication-provider>
```

Filter in web.xml:

```
<filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
```


----------



## MQue (13. Jan 2010)

OK, so wie unten kann ich mir den User schon mal holen, das kann ich in das Servlet schreiben, wenn sich der User das erste mal einlogged:


```
final String currentUser = SecurityContextHolder.getContext().getAuthentication().getName();
```


am besten wäre ein XML- Fragment, welches ich in die SpringSecurity.xml schreibe und welches mir bei einem erfolgreichem einloggen einmalig eine Methode aufruft.
Weiß jemand ob es sowas gibt?


----------



## byte (13. Jan 2010)

Naja, das hier wird ja sicher so nicht bleiben:
[xml]                <user-service>
                    <user name="test" password="testpassword" authorities="ROLE_USER, ROLE_ADMIN, ROLE_TELLER" />          
                    <user name="test1" password="test1password" authorities="ROLE_USER" />
                </user-service>
[/xml]

Für gewöhnlich implementiert man sich ja einen eigenen User-Service. Dort kannst Du Dein Logging dann unterbringen.


----------



## MQue (13. Jan 2010)

byte hat gesagt.:


> Naja, das hier wird ja sicher so nicht bleiben:
> [xml]                <user-service>
> <user name="test" password="testpassword" authorities="ROLE_USER, ROLE_ADMIN, ROLE_TELLER" />
> <user name="test1" password="test1password" authorities="ROLE_USER" />
> ...



Ursprünglich war angedacht, username und password in der Datenbank zu speichern, was ja ein leichtes ist mit dieser Implementierung, wurde aber bis auf weiteres wieder verworfen, daher nehme ich an, dass es mal so bleibt. 
Wüstest du vielleicht einen Link, wo ich finden kann, wie man einen eigenen User-Service implementiert und dann in den <authentication-provider> einhängt?

Besten Dank,


----------



## byte (13. Jan 2010)

Du musst einfach nur das Interface 
	
	
	
	





```
UserDetailsService
```
implementieren. Das Interface hat die Methode 
	
	
	
	





```
public UserDetails loadUserByUsername(String userId)
```
 und liefert entsprechend das User Objekt, dass dann in die Authentication gehängt wird.

Wenn Du die Klasse geschrieben hast, brauchst Du sie nur als eigene Bean in Spring deklarieren und mit Deinem AuthenticationProvider verdrahten. Wie das geht, steht in der Reference Documentation von Spring Security.


----------



## MQue (13. Jan 2010)

Habs auch gerade gefungen, 2.2.3 von der Spring Security Doku, Besten Dank,
lg


----------



## byte (13. Jan 2010)

Nichts zu danken. Einfach auf "Danke" drücken!


----------

