Security bei Spring?

Status
Nicht offen für weitere Antworten.

internet

Top Contributor
Hallo,
ich wollte mal nachfragen, wie man bei Spring die Security realsieren kann.
Also, dass zum Beispiel nur User mit bestimmter Rolle die Methode ausführen können.

userInRole gibt es ja bei den Richfaces!
Und bei EJB gibt es eben auch diverse Annotationen.
Wie macht man dies mit Spring?
 

Bin auch gerade beim durchackern von Spring Security (Doku Seite 5). Was mir nicht ganz klar ist sind die Namespaces? Für was brauche ich diese?


Code:
The namespace is designed to capture the most common uses of the framework and provide a simplified and
concise syntax for enabling them within an application.

Diesen Satz kappier ich nicht ganz wobei ich auch sagen muss, dass mir noch der Überblick fehlt.
Die ganze Konfiguration von Spring ist ja in <beans>...</beans> eingebettet, das versteh ich momentan unter Namespace!?

PS: Was mir noch nicht ganz klar ist, ist das Konfigurieren des filters in web.xml:

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

Wenn ich das so machen bekomme ich die Exception:

Code:
SCHWERWIEGEND: Exception starting filter springSecurityFilterChain
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:387)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:971)

ich hab jetzt keine Anhnung was ich in applicationContext.xml reinschreiben muss, mir ist klar, dass es eine bean mit der id springSecurityFilterChain sein muss, aber was muss das für eine Klasse sein?

und noch was, aus der Spring Security doku geht nicht klar hervor, wo man

Code:
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
hinschreiben muss? in web.xml oder applicationContext.xml oder in eine jsp - ich hab keine Ahnung?

vielen Dank für Hilfe,
lg
 
Zuletzt bearbeitet:
So, bin durchgestiegen, jetzt im nachhinein ist alles klar, deshalb bitte meine blöden Fragen vom vorigen Post ignorieren.
lg
 
Könntest du das vielleicht ein wenig zusammenfassen:

Ich brauche zB so etwas, dass man deklarieren, welche Rollen eine Methode ausführen dürfen in der Weboberfläche.

Und welche Rollen welche Webseite aufrufen / angezeigt bekommen.
zB ein Gast soll / darf nicht die Webseiten sehen, die ein Admin aufrufen kann, durch die URL einfach abändern. Sprich der Gast sieht wie die URL aussieht, und gibt einfach mal im Browser die URL statt "user" -> "admin" ein.
BSP

Admin
domain/admin/user.jsf

Gast:
domain/user/user.jsf

Wäre sehr nett, wenn du mir ein wenig Hilfe leisten könntest, ohne, dass ich 1000 Seiten durchlesen muss =)
 
hallo,
gibt es denn zum thema nicht mal eine schritt für schritt anleitung von einem kleinen beispiel?
 
Hi,
was ist denn an der Doku auf der Springseite so schlecht?Da ist doch wirklich alles vorhanden, was man braucht!
Und in den jars von Spring Security gibt es auch 2 Beispiele!

Grüße
Peter
 
ich möchte vorerst nur meine URL schützen.
Wie kann ich das einfach realisieren?

In den Beispielen habe ich immer wieder gesehen, dass dort mehrere Benutzernamen und dessen Passwort in der web.xml steht.
Ich greife allerdings diese Daten von meiner Datenbank ab.
Wie mache ich das dann?

Ich habe in meiner DB eine Tabelle "benutzer", wo auch das Passwort hinterlegt ist.
Und auch eine Tabelle "rolle".

Kann mir bitte jemand weiterhelfen.
 
Hi,

einmal hier: 2.2.3 Using other Authentication Providers

und deine Tabellen müssen so aussehen:
SQL:
  create table users(
      username varchar_ignorecase(50) not null primary key,
      password varchar_ignorecase(50) not null,
      enabled boolean not null);

  create table authorities (
      username varchar_ignorecase(50) not null,
      authority varchar_ignorecase(50) not null,
      constraint fk_authorities_users foreign key(username) references users(username));
      create unique index ix_auth_username on authorities (username,authority);

Das steht aber alles in der Spring-Doku....

Grüße
Peter
 
müssen die Tabellen / Attribute genauso heißen?
Können diese Tabellen auch zusätzliche Attribute beinhalten?
Oder geht auch das hier: (RACF = Benutzername)

Code:
CREATE TABLE IF NOT EXISTS rolle(
	rolle_id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
	rolle_auswahl NVARCHAR(20) NOT NULL,
	bemerkung NVARCHAR(50),
	emailadresse_1 NVARCHAR(50) NOT NULL,
	emailadresse_2 NVARCHAR(50)
);


CREATE TABLE IF NOT EXISTS benutzer(
	benutzer_id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
	passwort NVARCHAR(128) NOT NULL,
	zugang_erlaubt boolean NOT NULL,
	freigeschaltet boolean NOT NULL,
	person_fk BIGINT NOT NULL,
	rolle_fk BIGINT,
	FOREIGN KEY (person_fk) REFERENCES person(person_id),
	FOREIGN KEY (rolle_fk) REFERENCES rolle(rolle_id)
);


CREATE TABLE IF NOT EXISTS person(
	person_id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
	vorname NVARCHAR(32) NOT NULL, 
	nachname NVARCHAR(32) NOT NULL,
	email NVARCHAR(50),
	racf NVARCHAR(7),
);
 
Hi,

müssen die Tabellen / Attribute genauso heißen?
Nein, du mußt dann aber deinen Provider anpassen. Bei mir sieht das dann so aus:
[XML]
<security:jdbc-user-service id="authenticationDAO"
data-source-ref="dataSource"
authorities-by-username-query="SELECT username, role.name AS authority FROM user, `role`, user_role WHERE user.id = user_role.user_id AND role.id = user_role.role_id AND user.username = ?"
users-by-username-query="SELECT username ,password ,active AS enabled FROM user WHERE username = ?"/>
[/XML]
Wichtig ist, das natürlich irgendwo in deiner Tabelle die geforderten Attribute auftauchen..


Können diese Tabellen auch zusätzliche Attribute beinhalten?
Ja. kein Problem!

Grüße,
Peter
 
wie sehen deine Tabellen aus?
Welche Werte haben diese? (Insbesonderen die Werte der Rollen interessieren mich)
 
Hi,

SQL:
CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(200) collate latin1_general_ci default NULL,
  `surname` varchar(200 collate latin1_general_ci default NULL,
  `username` varchar(200) collate latin1_general_ci default NULL,
  `password` varchar(200) collate latin1_general_ci default NULL,
  `active` tinyint(1) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci  ;
  
  
CREATE TABLE IF NOT EXISTS `user_role` (
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
  
  CREATE TABLE IF NOT EXISTS `role` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(200) collate latin1_general_ci default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci  ;

ROLE_USER,ROLE_XYZ,..

Grüße
Peter
 
ok, vielen Dank.
Du hast dann eine n:m Beziehung zwischen Benutzer und Rollen?
Also ein Benutzer kann mehrere Rollen haben (macht für mich kein Sinn)
Und eben eine Rolle kann mehrere Benutzer haben?


Wie sieht denn deine Login - Methode aus?
 
Hi,

Also ein Benutzer kann mehrere Rollen haben (macht für mich kein Sinn)
Wieso nicht? Ein Benutzer kann zb. ein Abteilungsleiter und gleichzeitig auch ein Administrator sein!
Hier ist ein guter Artikel dazu.

Login-Methode gibt es nicht, alles weitere wird in der context.xml konfiguriert!

Grüße
Peter
 
Vielen Dank für den Artikel. Ist echt super.

Kannst du die context.xml bitte hier posten.
Wie sieht der Login / Logout - Button/Link bei dir auf der JSF- Seite aus?
 
Hi,

leider kann ich dir die context.xml nicht zeigen. Ich benutze aber sowieso kein JSF sondern Spring MVC, insofern würde es dir, glaube ich, auch nichts bringen. Aber eigentlich steht das Wesentliche in der context.xml doch auch schon hier auf der Seite...

Grüße
Peter
 
Naja, aber ich benötige doch eine LoginBean?

Bzw. eine Login - Methode?

Wie sollte ich mich sonst einloggen auf der Startseite o.Ä.?
 
Hi,

schau mal hier und hier ! (Ist leider etwas älter!)

Die LoginBean muss deinen Benutzernamen(j_username) und dein Passwort(j_password) enthalten und deine action muss an "j_spring_security_check" redirecten.

Den Rest übernimmt dann ja Spring für dich.

Grüße
Peter
 
OK:
hier meine context:
Passt die Query so mit den obengeschriebenen Tabellen?


=> Ich bekomme aber in der Methode immer eine NULLPOINTER EXCEPTION

Hier krachts: Authentication result = am.authenticate(request);


Java:
<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Sample namespace-based configuration
  -
  -->

<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 [url]http://www.springframework.org/schema/beans/spring-beans-3.0.xsd[/url]
                        [url=http://www.springframework.org/schema/security]Index of /schema/security[/url] http://www.springframework.org/schema/security/spring-security-3.0.xsd">

    <global-method-security pre-post-annotations="enabled">
        <!-- AspectJ pointcut expression that locates our "post" method and applies security that way
        <protect-pointcut expression="execution(* bigbank.*Service.post*(..))" access="ROLE_TELLER"/>
        -->
    </global-method-security>


    <http use-expressions="true">
        <!-- <intercept-url pattern="/admin/**" 						access="hasRole('ROLE_ADMIN')"/>--> 
         <intercept-url pattern="/admin/**" 									access="ROLE_ADMIN"/> 
        <intercept-url pattern="/personenverwaltung/**" 						access="ROLE_ADMIN"/>
        <intercept-url pattern="/personenverwaltung/createPerson.xhtml" 		access="ROLE_ADMIN"/>
        <intercept-url pattern="/secure/**" 									access="isAuthenticated()" />
        
        <!-- Disable web URI authorization, as we're using <global-method-security> and have @Secured the services layer instead
        <intercept-url pattern="/listAccounts.html" access="isRememberMe()" />
        <intercept-url pattern="/post.html" access="hasRole('ROLE_TELLER')" />
        -->
        <!-- <intercept-url pattern="/**" access="permitAll" /> -->
        
		<form-login
			login-processing-url="/j_spring_security_check"
			login-page="/index.xhtml"
			default-target-url="/admin/index.xhtml"
			authentication-failure-url="/index.xhtml" />
        <logout 	logout-success-url="/index.xhtml"/>
        <remember-me />
		
		<!-- Uncomment to enable X509 client authentication support <x509 /> -->
        
        
        <!-- Uncomment to limit the number of sessions a user can have 
        <session-management invalid-session-url="/faces/common/timeout.xhtml">
            <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
        </session-management>
        -->
    </http>

	
	

	
	

     <authentication-manager>  
         <authentication-provider>  
             <jdbc-user-service 
	             data-source-ref="dataSource"
	             authorities-by-username-query="SELECT person.racf AS username, rolle.rolle_auswahl AS authority FROM person, `role`, rolle WHERE rolle.id = benutzer.rolle_fk AND person.id = benutzer.person_fk AND person.racf = ?" 
	             users-by-username-query="SELECT person.racf AS username, benutzer.passwort AS password ,active AS enabled FROM person, benutzer WHERE person.racf = ?"/>  
         </authentication-provider>  
     </authentication-manager>  
</beans:beans>


und hier die Login - Methode

Java:
 public String login() {
        try {
            Authentication request = new UsernamePasswordAuthenticationToken(this.getRacf(), getPassword());
            Authentication result = am.authenticate(request);
            SecurityContextHolder.getContext().setAuthentication(result);

        } catch (AuthenticationException e) {
            
			createFacesMessage(MESSAGES_BENUTZERVERWALTUNG,
					"einloggen.failedRacf",
					"formLoginEingabe:racf",
					SEVERITY_ERROR);
			return null;
        }
        return "/admin/index";
    }
 
Hi,

wo ist denn deine "dataSource", ist die in einer anderen context.xml? Leider weiß ich nicht, wie das bei JSF geht, aber der Login-Kram wird dir vollständig von Spring abgenommen, du brauchst keine LoginMethode! Schau dir mal oder debug mal im SourceCode die Klasse "AuthenticationProcessingFilter" von Spring Security. Hier
 
die ist in der jpa.xml

Oder muss ich diese auch in der context von springsecurity machen?
Bzw. muss ich diese irgendwie "verlinken" / in der context von springsecurity angeben?
 
..das mit der LoginBean liegt wahrscheinlich eher an JSF als an Spring-Security. Abgesehen davon würde ich nicht unbedingt ein GAE-Besipiel als Referenz nehmen, da dort einige Dinge komplett anders laufen. Du hast dir mit Spring Security und JSF halt zwei nicht triviale Technologien ins Haus geholt. Ich kann dir halt zu JSF nix sagen...
 
ok, lassen wir das login mal außen vor.

Das Sperren von URL muss ja auch so gehen, das hat ja nichts mit JSF zu tun?

[XML]<intercept-url pattern="/admin/**" access="ROLE_ADMIN"/> [/XML]

heißt doch: dass alle Seiten, die im Ordner "admin" nur die Rolle "ROLE_ADMIN" sehen können, richtig?
ROLE_ADMIN ist ein Wert in der Tabelle Rolle in der Spalte (bei mir rolle_auswahl)?

Leider funktioniert das auch noch nicht.
Hast du dir die Query mal angeschaut? Ist das so korrekt?
 
Hi,

müßte es nicht so heißen?Versuch doch deine Querys mal mit Hibernate Tools auszuführen, da kannst du HQL-Abfragen testen.
SQL:
authorities-by-username-query="SELECT person.racf, rolle.rolle_auswahl AS authority FROM person, `role`, rolle WHERE rolle.id = benutzer.rolle_fk AND person.id = benutzer.person_fk AND person.racf = ?"
SQL:
users-by-username-query="SELECT person.racf , benutzer.passwort  ,active AS enabled FROM person, benutzer WHERE person.racf = ?"/>

heißt doch: dass alle Seiten, die im Ordner "admin" nur die Rolle "ROLE_ADMIN" sehen können, richtig?
Richtig!

Ich empfehle dir aber trotzdem, dich mal hinzusetzen und die Spring-Security-Doku durchzulesen, dir die Beispiele anzuschauen und dich mit dem Thema ausführlich zu befassen, weil eine falsche Konfiguration der Authentifizierung/Authorisierung unter Umständen schlimmer sein kann, als gar keine!


Grüße
Peter
 
So ich habe es nun hinbekommen, dass ich (teilweise) die Seite schützen kann.
Jetzt habe ich allerdings ein Problem beim Login.
Wenn ich richtigen Benutzername (RACF) und Passwort eintrage, dann werde ich auf die Seite
loginError.xhtml umgeleitet.
Wenn ich mich falsch einlogge auf die Seite j_spring_security_check.
Allerdings heißt es dann, dass es die Seite nicht geben würde.

Ist die Definition so richtig:
login-page = Seite wo das Login Formular ist
default-target-url= Ziel nach einloggen
authentication-failure-url = Seite wenn ein Fehler auftritt

Aber was login-processing-url weiß ich nicht so genau!
Weißt du das?
Hier mal:

Code:
		<form-login
			login-processing-url="/faces/j_spring_security_check"
			login-page="/faces/index.xhtml"
			default-target-url="/faces/index.xhtml"
			authentication-failure-url="/faces/common/loginError.xhtml" />
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben