Saturday, August 30, 2014

Creating your own OAuth2 server and clients using spring security - part 1

In this series of posts, I'll try to put together a simple working example on how to create your own OAuth2 server.

if you want to know more on OAuth2 and when to use it as authentication and authorization protocol then you can search about it on google and i'll put some URLs later.

Now I assume you are familiar with java web applications using Spring and maven.

to get started we need to create the server side with all dependencies required and i'll list them here, i'll use maven 2 to ease downloading dependencies for us.


Steps:

1- Create new maven project with arch type webapp:



2- Add the required depenedencies for spring, spring security, spring-oauth2, hibernate & other libraries (required for this tutorial only you can use other libraries if you like)

https://gist.github.com/anonymous/d33a31ddc3ba84375cf3

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.blabadi</groupId>
<artifactId>testoauth-server</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>testoauth Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<springframework.version>3.2.2.RELEASE</springframework.version>
<junit.version>4.10</junit.version>
<log4j.version>1.2.17</log4j.version>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
<spring.security.version>3.1.3.RELEASE</spring.security.version>
<groupId>org.springframework.security.oauth</groupId>
<oauth2.version>1.0.0.RELEASE</oauth2.version>
<org.slf4j.version>1.6.1</org.slf4j.version>
</properties>
<dependencies>
<!--===================== Spring dependencies =======================-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<artifactId>spring-expression</artifactId>
<groupId>org.springframework</groupId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<artifactId>spring-aop</artifactId>
<groupId>org.springframework</groupId>
<version>${springframework.version}</version>
</dependency>
<!-- Spring AOP dependency -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<artifactId>spring-tx</artifactId>
<groupId>org.springframework</groupId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
<version>${springframework.version}</version>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<!--========================== servlets api ======================-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.3</version>
<scope>provided</scope>
</dependency>
<!--============================= Jackson ===========================-->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.3</version>
</dependency>
<!--============================ Logging ==========================-->
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- Log4j slf4j impl
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
<scope>runtime</scope>
</dependency>
-->
<!--======================= Testing libs ============================-->
<!-- JUnit testing framework -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- spring test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springframework.version}</version>
<scope>test</scope>
</dependency>
<!-- needed to get AOPs around the test cases -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.2.2</version>
<scope>test</scope>
</dependency>
<!-- mocks lib -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
</dependency>
<!-- in memory db -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.2.9</version>
<scope>test</scope>
</dependency>
<!--======================== hibernate =====================-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.10.Final</version>
</dependency>
<!-- MySQL database driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<!-- OAuth 2.0 dependencies -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${oauth2.version}</version>
</dependency>
</dependencies>
<build>
<finalName>testoauth-server</finalName>
</build>
</project>
<!--
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
-->
view raw pom.xml hosted with ❤ by GitHub
3- I used hibernate to automate the creation of the schema required by spring OAuth2 to manage tokens (it's required to have schema created in db if you are using jdbc token store).
I use wamp server and phpmyadmin to create my database

4- Setup hibernate mapping [I used xml file, but I think annotations will work too]

https://gist.github.com/anonymous/f713fd84a1618b04c04a
package com.blabadi.sec.oauth.entities;
public class AccessToken {
private String token_id;
private byte[] token;
private String authentication_id;
private String user_name;
private String client_id;
private byte[] authentication;
private String refresh_token;
public String getToken_id() {
return token_id;
}
public void setToken_id(String token_id) {
this.token_id = token_id;
}
public byte[] getToken() {
return token;
}
public void setToken(byte[] token) {
this.token = token;
}
public String getAuthentication_id() {
return authentication_id;
}
public void setAuthentication_id(String authentication_id) {
this.authentication_id = authentication_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getClient_id() {
return client_id;
}
public void setClient_id(String client_id) {
this.client_id = client_id;
}
public byte[] getAuthentication() {
return authentication;
}
public void setAuthentication(byte[] authentication) {
this.authentication = authentication;
}
public String getRefresh_token() {
return refresh_token;
}
public void setRefresh_token(String refresh_token) {
this.refresh_token = refresh_token;
}
}
https://gist.github.com/anonymous/71fd66dc9e58956fb3bf
package com.blabadi.sec.oauth.entities;
public class RefreshToken {
public String getToken_id() {
return token_id;
}
public void setToken_id(String token_id) {
this.token_id = token_id;
}
public byte[] getToken() {
return token;
}
public void setToken(byte[] token) {
this.token = token;
}
public byte[] getAuthentication() {
return authentication;
}
public void setAuthentication(byte[] authentication) {
this.authentication = authentication;
}
private String token_id;
private byte[] token;
private byte[] authentication;
}
https://gist.github.com/anonymous/8d00471f278ae17b0792
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class
name="com.blabadi.sec.oauth.entities.AccessToken"
table="oauth_access_token">
<id name="token_id" type="string" >
<column name="token_id" />
</id>
<property name="token" type="blob">
<column name="token" />
</property>
<property name="authentication_id" type="string">
<column name="authentication_id" />
</property>
<property name="user_name" type="string">
<column name="user_name" />
</property>
<property name="client_id" type="string">
<column name="client_id" />
</property>
<property name="authentication" type="blob">
<column name="authentication" />
</property>
<property name="refresh_token" type="string">
<column name="refresh_token" />
</property>
</class>
<class
name="com.blabadi.sec.oauth.entities.RefreshToken"
table="oauth_refresh_token">
<id name="token_id" type="string" >
<column name="token_id" />
</id>
<property name="token" type="blob">
<column name="token" />
</property>
<property name="authentication" type="blob">
<column name="authentication" />
</property>
</class>
</hibernate-mapping>
view raw mapping.hbm.xml hosted with ❤ by GitHub

5- Create login service interface and stub implementation
https://gist.github.com/anonymous/bbd8eaa9dcc096c148e7
package com.blabadi.sec.oauth.provider;
import java.util.List;
public interface LoginService {
String login(String userName, String password);
List<String> getUserRoles(String userId);
boolean validateUserId(String userId);
}
https://gist.github.com/anonymous/eea11cbd2ced2d927515
package com.blabadi.sec.oauth.provider;
import java.util.List;
import org.springframework.stereotype.Component;
@Component
public class LoginServiceImpl implements LoginService {
public String login(String userName, String password) {
// TODO Auto-generated method stub
return null;
}
public List<String> getUserRoles(String userId) {
// TODO Auto-generated method stub
return null;
}
public boolean validateUserId(String userId) {
// TODO Auto-generated method stub
return false;
}
}


6- Create custom authentication provider
https://gist.github.com/anonymous/b73cf93b3d0c2534813e
package com.blabadi.sec.oauth.provider;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
public class CustomAuthenticationProvider implements AuthenticationProvider {
/** LoginService service bean */
@Autowired
LoginService loginSvc;
/** Logger */
private final static Logger logger = LoggerFactory.getLogger(CustomAuthenticationProvider.class);
/**
* Override the authenticate method to implement our custom authentication logic agains LoginService api.
*/
public Authentication authenticate(Authentication auth) throws AuthenticationException {
logger.debug("entered CustomAuthenticationProvider.authenticate() with arguments: {}", auth.toString());
//extract user name and password from Authentication instance
String userName = (String) auth.getPrincipal();
String password = (String) auth.getCredentials();
//call LoginService login to authenticate the user name and password
logger.debug("calling LoginService.login for user: {}", userName);
String userId = loginSvc.login(userName, password);
//check validity of the user Id returned, if it's valid => authentication successful.
if (loginSvc.validateUserId(userId)) {
logger.info("user {} authentication with LoginService was successful, found userId : {}", userName, userId);
logger.debug("getting user: {} roles from LoginService", userName);
List<String> userRoles = loginSvc.getUserRoles(userId);
logger.info("retrieved user roles from LoginService");
//create GrantedAuthority collection from retrieved roles
Collection<SimpleGrantedAuthority> authorties = fillUserAuthorities(userRoles);
//create a fully populated authentication object
Authentication filledAuthentication = new UsernamePasswordAuthenticationToken(userName, password, authorties);
logger.info("created fully populated authentication object {}", filledAuthentication.toString());
logger.debug("exiting authenticate()");
return filledAuthentication;
} else {
logger.error("authentication failed against LoginService, invalid userId : {} , was returned", userId);
//throw an exception to indicate failure of authentication process
throw new BadCredentialsException("Invalid credentials");
}
}
public boolean supports(Class<?> arg0) {
return true;
}
/**
* utility method to convert the user roles to a Collection<GrantedAuthority> for spring security to deal with
* @param roles the list of roles as string
* @return a collection of SimpleGrantedAuthority that represent user roles
*/
private Collection<SimpleGrantedAuthority> fillUserAuthorities(List<String> roles) {
Collection<SimpleGrantedAuthority> authorties = new ArrayList<SimpleGrantedAuthority>();
for(String role : roles) {
authorties.add(new SimpleGrantedAuthority(role));
}
return authorties;
}
}


7-Create the properties file required for db conneciton
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/testoauth
jdbc.username=root
jdbc.password=

8-Create spring-security.xml  (we will go over the contents in the next part)

https://gist.github.com/anonymous/1fb8ccb3b8e70b4ffa36

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<oauth:resource-server id="resourceServerFilter"
resource-id="custom_app" token-services-ref="tokenServices" />
<!-- ==================================== OAuth provider configurations
==================================== -->
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<!-- clients service -->
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="mobile_iphone"
authorized-grant-types="password,refresh_token,implicit" secret="custom_app_iphone"
authorities="ROLE_CLIENT" />
<oauth:client client-id="mobile_android"
authorized-grant-types="password,refresh_token,implicit" secret="custom_android"
authorities="ROLE_CLIENT" />
<oauth:client client-id="web_liferay"
authorized-grant-types="password,refresh_token,implicit" secret="custom_liferay"
authorities="ROLE_CLIENT" />
</oauth:client-details-service>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
<!--
Token configurations
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
-->
<bean id="jdbcTokenStore"
class="org.springframework.security.oauth2.provider.token.JdbcTokenStore">
<constructor-arg ref="secDataSource" />
</bean>
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="jdbcTokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<!-- token obtaining URL configurations -->
<http pattern="/oauth/token/**" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token/**" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- OAuth 2 related beans -->
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter" />
<!-- required to use ACL expressions like : hasRole('..') -->
<bean
class="org.springframework.security.web.access.expression.WebExpressionVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<!-- Entry points -->
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="custom" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="custom_app/client" />
<property name="typeName" value="Basic" />
</bean>
<!-- User approval handler -->
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<!-- ========================= OAuth protected urls config ============================== -->
<http pattern="/ws/(.*)" request-matcher="regex"
authentication-manager-ref="clientAuthenticationManager"
create-session="never" use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<sec:anonymous enabled="true" />
<intercept-url pattern="/ws/(.*)\?(wsdl|xsd)(.*)"
access="permitAll" />
<!--<intercept-url pattern="/ws/(.*)" access="hasRole('ROLE_USER')" /> -->
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<http pattern="/rest/eidentity/**" security="none"
xmlns="http://www.springframework.org/schema/security" />
<http pattern="/rest/**" authentication-manager-ref="clientAuthenticationManager"
create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/rest/register" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/rest/**" access="ROLE_USER" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!--==================================== Authentication managers ==================================== -->
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="customAuthenticationProvider"></authentication-provider>
<!-- TODO: FOR TEST ONLY !! REMOVE IN PRODUCTION ENVIRONMENT -->
<authentication-provider>
<user-service id="userDetailsService">
<user name="user" password="password" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
<bean id="customAuthenticationProvider"
class="com.blabadi.sec.oauth.provider.CustomAuthenticationProvider" />
<!--==================================== Enable Standard Pre/Post annotations
====================================== -->
<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<!--you could also wire in the expression handler up at the layer of the
http filters. See https://jira.springsource.org/browse/SEC-1452 -->
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
</beans>
9-Create security-beans.xml to gather spring configurations related to security in one place
https://gist.github.com/anonymous/cbc0dfd0b37a9b10ffd7
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- required resources -->
<import resource="classpath:spring-security.xml"/>
<!-- project config -->
<context:component-scan base-package="com.blabadi.sec.oauth.provider"></context:component-scan>
<!-- Hibernate session factory -->
<bean id="securitySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="secDataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>mapping.hbm.xml</value>
</list>
</property>
</bean>
</beans>


10-Create spring-beans.xml to gather all configurations in one file
https://gist.github.com/anonymous/f23913f0d24c7c1f6ac8
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<import resource="classpath:security-beans.xml"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:properties/testoauth-database.properties</value>
</list>
</property>
</bean>
<!-- testoauth db datasource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- security db datasource -->
<bean id="secDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
</beans>

11-Configure web.xml, and add mvc-dispatcher-servlet.xml
https://gist.github.com/anonymous/10ddabcdc86ec512de0a
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring-beans.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
Spring Security Filter Chain. This filter-name must not be changed.
The <http> namespace creates a Spring bean with this name and the DelegatingFilterProxy
will use this filter-name to delegate to the bean.
-->
<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>
</web-app>
view raw web.xml hosted with ❤ by GitHub
https://gist.github.com/anonymous/290eb03d05cc7e7a4776
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<mvc:resources mapping="/static/**" location="/static/"></mvc:resources>
<mvc:annotation-driven />
</beans>



after all this if I didn't forget anything you will have the following (click on the image to see it in original size):

2 comments:

  1. HI can you share the Database table structure which you have used with sample data and request URL for authorization, refresh token and authorization token.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete

Note: Only a member of this blog may post a comment.

Istio —simple fast way to start

istio archeticture (source istio.io) I would like to share with you a sample repo to start and help you continue your jou...