Spring MVC Security konfiguracija

Na samom startu svake Spring MVC web aplikacije susrećemo se sa konfiguracijom i pisanjem bean-ova koji ćemo kasnije koristiti.
Jedna od stvari koje ta konfiguracija sadrži su i security bean-ovi.
Dobra stvar Spring-a je da možemo da imamo definisanu sigurnost aplikacije na nivou bean-ova, bez pisanja dodatnog koda u Java klasama. Kad kažem sigurnost, mislim na login i autorizaciju korisnika za korišćenje aplikacije koja takvu funkcionalnost zahteva, naravno.

Spring MVC aplikacija ća automatski instancirati sve klase koje se nalaze u bean-ovima, tako da one ostaju spremne za korišćenje u Javi, što je, ispostavilo se, dosta praktično, i uveliko smanjuje broj napisanih linija koda.

Osnovna struktura aplikacije može izgledati npr. ovako:

1. servlet-context.xml – Osnovni konfiguracioni fajl

Prvo sto moramo da kreiramo svakako je servlet-context.xml.
On, u jednostavnoj varijanti potrebnoj za ovu priču, može izgledati ovako:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc 
                        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
                        http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd
                        ">
                        
	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	<context:component-scan base-package="com.ghcpro" />

	<!-- Configures the @Controller programming model -->
	<mvc:annotation-driven />

	<!-- Forwards requests to the "/" resource to the "welcome" view -->
	<mvc:view-controller path="/" view-name="home" />
	<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
	<mvc:resources mapping="/resources/**" location="/resources/" />

	<!-- MySQL Configuration -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/db_name" />
		<property name="username" value="root" />
		<property name="password" value="" />
	</bean>
    
    <!-- Transaction manager -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

Obavezan je DataSource bean, njega će Spring koristiti da bi se povezao na bazu i pročitao podatke o korisnicima.

	
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	<property name="driverClassName" value="com.mysql.jdbc.Driver" />
	<property name="url" value="jdbc:mysql://localhost:3306/db_name" />
	<property name="username" value="root" />
	<property name="password" value="" />
</bean>

Ostalo u servlet-context.xml fajlu su manje ili više standarne bean-ovi Spring aplikacije. Vi ćete svakako svoj proširiti i prilagoditi svojim potrebama.

2. security-context.xml – Konfiguracija Spring Security-a

Kada smo kreirali servlet-context.xml, biće nam potreban još jedan, security-context.xml.

Generalno, sve ovo može da bude definisano i u jednom xml-u, al radi bolje preglednosti, ipak ćemo ih razdvojiti u posebne fajlove.

Ovako izgleda security-context.xml

<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.3.xsd">

	<http use-expressions="true" auto-config="true" >
	    <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"  />
		<intercept-url pattern="/login*" filters="none" />
		<intercept-url pattern="/resources/**" filters="none" />
		<intercept-url pattern="/**" access="hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')" />
		<form-login login-processing-url="/j_spring_security_check" always-use-default-target="true" login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed" />
		<logout logout-url="/logout" logout-success-url="/" />
		<access-denied-handler error-page="/access-denied"/>
	</http>

	<authentication-manager>
		<authentication-provider>
			<jdbc-user-service data-source-ref="dataSource"
				users-by-username-query="select email as username, password, active as enabled from users where email=?"
				authorities-by-username-query="select u.email as username, concat('ROLE_', u.role) as authority from users u where u.email=?" />
		</authentication-provider>
	</authentication-manager>

</beans:beans>

O ovom xml-u definišemo prava pristupa delovima aplikacije, kao i inicijalnu autorizaciju korisnika.

Obratite pažnju na nekoliko stvari:

  1. Akcije u Spring VMC kontrolerima treba da odgovaraju definiciji u security bean-u
    <form-login login-processing-url="/j_spring_security_check" always-use-default-target="true" login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed" />
    <logout logout-url="/logout" logout-success-url="/" />
    <access-denied-handler error-page="/access-denied"/>
    

    što podrazumeva da će vaš npr. HomeController imati definisane akcije “login”, “loginfailed”, “access-denied” i “logout” url-ove, kako bi Spring znao da pravilno redirektuje određene zahteve. Naravno, prilagođavate po svojoj potrebi, ovo napominjem da bih ispratio konfiguraciju iz primera.

  2. Role moraju početi sa “ROLE_”. Dakle, mi ovde u primerima imamo ROLE_USER i ROLE_ADMIN (koje ćete koristiti ukoliko želite da razdvojite delove aplikacije na npr. deo za korisnike i deo za administratore). Za početak je ovo sasvim dovoljno. U ovom primeru vidimo kreiranje select upita da bismo dobili rezultat koji će Spring “razumeti”:
    concat('ROLE_', u.role) as authority
  3. SQL select upiti moraju imati naziv kolona kakav Spring očekuje, Ukoliko to nije slučaj, koristite alias-e kolona, kao ja u ovom primeru.

VAŽNO!

O ovom primeru je aplikacija konfigurisana tako da ne dozvoljava pristup bilo kom delu sajta ukoliko se korisnik nije prijavio, pored toga, deli aplikaciju na korisnički i administratorski deo. Ukoliko to nije potreba, izmenite “intercept-url” delove po želji.
Na primer, da biste dozvolili pristup kompletnom sajtu promenite intercept-url pravila u npr.

<intercept-url pattern="/**" filters="none" />

Prilagodite ostala “intercept-url” pravila po želji.
I obratite pažnju na redosled definisanja pravila! Spring će prestati da upoređuje pravila sa datim URL-um čim naiđe na prvo pravilo koji odgovara URL-u.

3. Login forma

I na kraju nam ostaje da napravimo login formu koja će se povezati sa Spring security-em.

Osnovna login forma izgleda ovako:

<c:if test="${not empty error}">
		<div class="error">
			Login failed. Please check your credentials and try again.<br /> 
			System error: ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}
		</div>
	</c:if>

	<form name='f' action="<c:url value='/j_spring_security_check' />" method='POST'>
		<table>
			<tr>
				<td>Email:</td>
				<td><input type='text' name='j_username' value=''>
				</td>
			</tr>
			<tr>
				<td>Password:</td>
				<td><input type='password' name='j_password' />
				</td>
			</tr>
			<tr>
				<td colspan="2" align="right"><input class="button blue" name="submit" type="submit" value="Login" />
				</td>
			</tr>
		</table>
	</form>

I Out-of-Box Spring Security je spreman.

Nadam se da će nekome ovo biti od pomoći.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s