Friday, November 26, 2010

Short Description of Shibboleth SSO

Core center of Shibboleth SSO are two components

1) IDP –Identity provider – It is software which is installed on the Server M/C which behaves as IDP for the request coming from SP.

2) SP – Service Provider – It is software which is installed on the Server M/C (where site which is access by the end user is strike) which is used to make a call to IDP to get the authentication for the user call.

Q 1) How Shibboleth SSO Work ?

Flow

User (through Browser) à hit to SP M/C i.e. where site is hosted and SP software is installedàHaving said SP software installed means on that M/C Shibboleth Service is in running mode. àThis SP M/C i.e. SP service divert this call to the IDP M/C. à Inside IDP M/C (Where IDP software is installed) take the call and divert it to implementation of IDP and show the user login page. à Once the user get logged in he/she will be diverted first page.

Description:

1) Identity Provider:

a) Installation

- Download and install Java 1.5+, Tomcat 5.5 (core) and Apache 2.2+. Install Tomcat at /usr/local/tomcat. Avoid other distributions of Tomcat, such as from yum. Make sure the $JAVA_HOME environment variable points at the root of your JDK.

- Download the IdP .bin binary installer fromhttp://shibboleth.internet2.edu/downloads/shibboleth/idp/2.1.1/, unzip it, and move to that directory.

curl -O http://shibboleth.internet2.edu/downloads/shibboleth/idp/2.1.1/shibboleth-identityprovider-2.1.1-bin.zip

unzip shibboleth-identityprovider-2.1.1-bin.zip

cd identityprovider/

- Run sh install.sh. This is a new installation. Please use /usr/local/idp for your IdP directory.

sh install.sh

- Configure Apache by adding the following line to mod_proxy_ajp.conf or httpd.conf to pass requests for the IdP into Tomcat:

ProxyPass /idp/ ajp://localhost:8009/idp/

Enable Tomcat to run the IdP by endorsing additional libraries for XML processing.

cp endorsed/*.jar /usr/local/tomcat/common/endorsed/

- Add request.tomcatAuthentication="false" and Address="127.0.0.1" to Tomcat's /usr/local/tomcat/conf/server.xml port 8009 AJP13 connector so Apache can relay usernames to the IdP.

request.tomcatAuthentication="false" address="127.0.0.1" />

Define the following in httpd.conf or ssl.conf to front-end your IdP with basic authentication.

AuthType Basic

AuthName "My Identity Provider"

AuthUserFile /usr/local/idp/credentials/user.db

require valid-user

- Create a test user or two using the htpasswd command.

htpasswd -c /usr/local/idp/credentials/user.db spiderman

- Install the IdP into Tomcat.

cp /usr/local/idp/war/idp.war /usr/local/tomcat/webapps/

Note: Here we had used Apache as the request from SP may come from any server i.e. SP site may be hosted on any technology i.e. Perl, PHP, JAVA and on beck end of Apache server implementation of IDP (idp.war) is done on the Apache Tomcat.

2) Service Provider:

b) Installation

Take SP software set up for specified M/C i.e. if my site is hosted on TOMCAT on Window M/C then I Need SP Software for Window Machine. Choose the installation for above requirement fromhttps://spaces.internet2.edu/display/SHIB2/NativeSPWindowsApacheInstaller

Configuration:

This is the most important part of Shibboleth

Note: below given changes are done keeping in mind

IDP à Apache + Apache Tomcat

SP à Installed on Window M/C with Setup for Apache.

è Apache is installed on window M/C at path

C:\Program Files\Apache Software Foundation\Apache2.2\bin

è Tomcat is installed on Window M/C at path

C:\apache-tomcat-5.5.28\bin

è IDP software is installed at path

C:\opt\shibboleth-idp

è SP is installed on Window M/C at Path

C:\opt\shibboleth-sp

Following are the changed made into the respective file of the servers:

1) C:\Program Files\Apache Software Foundation\Apache2.2\conf\httpd.conf

2) C:\apache-tomcat-5.5.28\conf\server.xml

3) C:\opt\shibboleth-idp\conf\relying-party.xml

4) C:\opt\shibboleth-sp\etc\shibboleth\shibboleth2.xml

Changes Description:

1) httpd.Conf

a) Listen 8443 https : to indicate Apache should listen to port 8443 for https protocol.

b) UseCanonicalName on : use to tell Apache to use basic name of the server rather than ip address.

c) LoadModule proxy_module modules/mod_proxy.so : use to tell apache to use proxy .so when requested.

d) LoadModule proxy_ajp_module modules/mod_proxy_ajp.so : use to tell apache to use proxy .so when ajp request comes.

e) LoadModule proxy_http_module modules/mod_proxy_http.so : use to tell apache to use proxy .so for http request.

f) ServerName servername:80 – indicating that Apache server is listening at port 80.

g) #By siddhu for Shiboleth

Include C:/opt/shibboleth-sp/etc/shibboleth/apache22.config

h) #By siddhu for shibboleth

ProxyPass /idp/ ajp://localhost:8009/idp/ : this tell the apache server to divert the call from any request which contain /idp/ in url to ajp://localhost:8009/idp/ which is out Apache Tomcat running behind the Apache at IDP end on port 8009 to show the login screen to the user.

i)

AuthType Basic

AuthName "My Identity Provider"

AuthUserFile C:/opt/shibboleth-idp/credentials/user.db : this show the db where user credential is kept for Authetication.

require valid-user

2) server.xml : Telling apache server to redirect the response from Apache Tomcat at port 8009 to Apache on address 127.0.0.1 at 8443 port.

enableLookups="false" redirectPort="8443" protocol="AJP/1.3" request.tomcatAuthentication="false" address="127.0.0.1"/>

3) relying-party.xml:

The most important file that need to be configure at the IDP end . IDP of Shibboleth depends on the configuration of this file for all the request from SP.

Main parameter need to be taken into consideration while using relying-party.xml are

a) AnonymousRelyingParty :

This tag provide the relying party entityid address i.e. http://localhost/idp/shibboleth this entity id is the common between both IDP and SP.

b) DefaultRelyingParty :

defaultSigningCredentialRef="IdPCredential">

This tag provide the relying party entityid address i.e. http://localhost/idp/shibboleth this entity id is the common between both IDP and SP.

c) MetadataProvider:

metadataURL="http://localhost/Shibboleth.sso/Metadata"

backingFile="C:\opt\shibboleth-idp/metadata/local_testshib.xml">

this tag gives information that this IDP used FileBackedHTTPMetadataProvider means it take the values /metadata from the url i.e. metadataURL="http://localhost/Shibboleth.sso/Metadata"and store it at local on path backingFile="C:\opt\shibboleth-idp/metadata/local_testshib.xml">

here http://localhost/Shibboleth.sso/Metadata terms need to be common between the IDP and SP configuration. IDP and SP understand only this unique Entity ID.

d) Security: this show which key and certificate is used by the IDP to verify the data which is came from the SP.

C:\opt\shibboleth-idp/credentials/idp.key

C:\opt\shibboleth-idp/credentials/idp.crt

4) shibboleth2.xml

This is the most common and important file for configuration for the SP side of the shibboleth.

Main parameter need to be taken into consideration while using shibboleth2.xml are

a) ApplicationDefaults: here we will specify the name of Entity Id which should match to the name which we had given for configuration of IDP.

b) SessionInitiator : this tag maps the entityid and maintain a session. AssertionConsumerService tells which protocol is supported by this SP for the request coming from IDP i.e. SAML2 or SAML and which method POST or GET. Generally it is POST. Acl parameter indicate the address where the server is installed.

c) MetadataProvider: this MetadataProvider contains the information which should match with the MetadataProvider of the IDP MetadataProvider in C:\opt\shibboleth-idp\conf\relying-party.xml.

How to run the whole process

1) Make above all configuration changes

2) Start Shibboleth services from services.msc from the SP M/C indicating that all the request from the client or end user to this site hosted on this M/C is intercepted by this process.

3) Start Apache server using

C:\Program Files\Apache Software Foundation\Apache2.2\bin>httpd -D SSL -k start

4) Start Tomcat

Note Please refer to the following log for each above steps:

C:\Program Files\Apache Software Foundation\Apache2.2\logs\error.log

C:\opt\shibboleth-sp\var\log\shibboleth\native.log

C:\opt\shibboleth-sp\var\log\shibboleth\shibd.log

C:\opt\shibboleth-idp\logs\idp-process.log

Testing:

After doing the above 4 step check that all IDP and SP are running as per need:

-For Tomcat – this will give the root page of the tomcat indicating tomcat is running properly

http://localhost:8080/

-For Apache – this will give the root page for Apache server

http://localhost:8443/

- To check IDP – this will give ok as output indicating that IDP is installed and running properly.

http://localhost:8080/idp/profile/Status

- To check SP on Apache -- we will get xml as out put is example we can check for the EntityId

http://localhost:8443/Shibboleth.sso/Status http://localhost:8443/Shibboleth.sso/Session

-Finally Hit following url

http://localhost:8443/secure

or

http:localhost/secure

this will divert you to login screen which you had developed … enter the user id and password which you had created

====Files changes to configure Shibboleth IDP 2.1.0 with Shibboleth 2.3.1 for Local DB

1) C:\Program Files\Apache Software Foundation\Apache2.2\conf\httpd.confListen 8443 httpsUseCanonicalName on
LoadModule proxy_module modules/mod_proxy.soLoadModule proxy_ajp_module modules/mod_proxy_ajp.soLoadModule proxy_http_module modules/mod_proxy_http.soLoadModule ssl_module modules/mod_ssl.soServerName servername:80
#By siddhu for ShibolethInclude C:/opt/shibboleth-sp/etc/shibboleth/apache22.config
#By siddhu for shibbolethProxyPass /idp/ ajp://localhost:8009/idp/ AuthType Basic AuthName "My Identity Provider" AuthUserFile C:/opt/shibboleth-idp/credentials/user.db require valid-user
2) C:\apache-tomcat-5.5.28\conf\server.xml
3) C:\opt\shibboleth-idp\conf\relying-party.xml

4) C:\opt\shibboleth-sp\etc\shibboleth\shibboleth2.xml
5) C:\opt\shibboleth-idp\conf\handler.xml
/Metadata/SAML -- Uncommented this line urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
6) C:\opt\shibboleth-sp\var\run\shibboleth\local_testshib-two-idp-metadata.xml
8) finally if you get message as service registered but not singed then Modify File local_testshib-two-idp-metadata.xml at C:\opt\shibboleth-sp\var\run\shibboleth\local_testshib-two-idp-metadata.xml from C:\opt\shibboleth-sp\etc\shibboleth\shibboleth2.xmland copied the value of idp.crt into the local_testshib-two-idp-metadata.xml and problem solved.

8) Create a secure folder inside Apache Server and put your first page.C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\secure
i.e. C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\secure\index.html

==For Log -- Check this

C:\Program Files\Apache Software Foundation\Apache2.2\logs\error.log

C:\opt\shibboleth-sp\var\log\shibboleth\native.log

C:\opt\shibboleth-idp\logs\idp-process.log



======Files changes to configure LDAP for Shibboleth IDP 2.2.0 and Shibboleth SP 2.3.1

1) C:\opt\shibboleth-idp\conf\login.config

edu.vt.middleware.ldap.jaas.LdapLoginModule required

host="localhost"

port="10389"

base="ou=users"

userField="uid";

2) C:\opt\shibboleth-idp\conf\handler.xml


jaasConfigurationLocation="file://C:\opt\shibboleth-idp/conf/login.config" authenticationDuration="720">

urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport

3) C:\opt\shibboleth-idp\conf\logging.xml

4) C:\opt\shibboleth-idp\conf\relying-party.xml


defaultSigningCredentialRef="IdPCredential" />

defaultSigningCredentialRef="IdPCredential"

defaultAuthenticationMethod="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport">

includeAttributeStatement="true"

assertionLifetime="PT5M"

assertionProxyCount="0"

signResponses="conditional"

signAssertions="never"

encryptAssertions="conditional"

encryptNameIds="conditional" />

assertionLifetime="PT5M"

assertionProxyCount="0"

signResponses="conditional"

signAssertions="never"

encryptAssertions="conditional"

encryptNameIds="conditional" />

signResponses="conditional"

signAssertions="never"

encryptAssertions="conditional"

encryptNameIds="conditional" />

metadataURL="http://localhost/Shibboleth.sso/Metadata"

backingFile="C:/opt/shibboleth-idp/metadata/local_testshib.xml">


5) C:\opt\shibboleth-idp\conf\attribute-resolver.xml


ldapURL="ldap://localhost:10389"

baseDN="ou=system"

principal="uid=admin,ou=system"

principalCredential="secret"

lowercaseAttributeNames="true">

(uid=$requestContext.principalName)

]]>

6) C:\opt\shibboleth-sp\etc\shibboleth\shibboleth2.xml

7) C:\apache-tomcat-5.5.28\webapps\idp\login.jsp -- No Change

8) C:\apache-tomcat-5.5.28\webapps\idp\WEB-INF\web.xml -- No Change

9) C:\Program Files\Apache Software Foundation\Apache2.2\conf\httpd.conf

Listen 80

Listen 8443 https

UseCanonicalName on

LoadModule proxy_module modules/mod_proxy.so

LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

LoadModule proxy_http_module modules/mod_proxy_http.so

LoadModule ssl_module modules/mod_ssl.so

ServerName servername:80

#By siddhu for Shiboleth

Include C:/opt/shibboleth-sp/etc/shibboleth/apache22.config


ProxyPass /idp/ ajp://localhost:8009/idp/

AuthType Basic

AuthName "My Identity Provider"

require valid-user



10) Created a File local_testshib.xml by hitting http://localhost/Shibboleth.sso/Metadata of metadataURL="http://localhost/Shibboleth.sso/Metadata"

inside relying-party.xml and copy/download the output File into the location with name local_testshib.xml

C:\opt\shibboleth-idp\metadata\local_testshib.xml



(11) finally if you get message as service registered but not singed then Modify File local_testshib-two-idp-metadata.xml at C:\opt\shibboleth-sp\var\run\shibboleth\local_testshib-two-idp-metadata.xml from C:\opt\shibboleth-sp\etc\shibboleth\shibboleth2.xml

and copied the value of idp.crt into the local_testshib-two-idp-metadata.xml and problem solved.


Tuesday, November 16, 2010

Sending Mail using JAVA Class

PostMail: This class can be used to send mail using JAVA Class.

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class PostMail {

public void postMail( String recipients[ ], String subject, String message , String from) throws MessagingException
{
boolean debug = false;


Properties props = new Properties();
props.put("mail.smtp.host", "smtp.jcom.net");


Session session = Session.getDefaultInstance(props, null);
session.setDebug(debug);


Message objMessage = new MimeMessage(session);


InternetAddress addressFrom = new InternetAddress(from);
objMessage.setFrom(addressFrom);

InternetAddress[] objAddressTo = new InternetAddress[recipients.length];
for (int i = 0; i <>
{
objAddressTo[i] = new InternetAddress(recipients[i]);
}
objMessage.setRecipients(Message.RecipientType.TO, objAddressTo);



objMessage.addHeader("MyHeaderName", "myHeaderValue");


objMessage.setSubject(subject);
objMessage.setContent(message, "text/plain");
Transport.send(objMessage);
System.out.println("Message is send properly:");
}

public static void main(String args[])
{
try
{
PostMail objPostMail = new PostMail();
String[] objStringArray = new String[1];
objStringArray[0] = new String("siddhartha.dhumale@yahoo.com");
objPostMail.postMail(objStringArray, "Hi Subject", "Hi this is siddharatha", "siddharathadhumale@gmail.com");
}catch (Exception e)
{
e.printStackTrace();
}
}
}

Integration of GWT with Spring Security




GWTSpringSecurity : This example is used to integrate Spring Security with GWT.

AuthenticationService:

package com.seewah.sample.gwtspring.client;

import com.google.gwt.core.client.GWT;

import com.google.gwt.user.client.rpc.RemoteService;

import com.google.gwt.user.client.rpc.ServiceDefTarget;

public interface AuthenticationService extends RemoteService {

public static final String SERVICE_URI = "authenticationService";

public static class Util {

public static AuthenticationServiceAsync getInstance() {

AuthenticationServiceAsync instance = (AuthenticationServiceAsync) GWT.create(AuthenticationService.class);

ServiceDefTarget target = (ServiceDefTarget) instance;

target.setServiceEntryPoint(GWT.getModuleBaseURL() + SERVICE_URI);

return instance;

}

}

/**

* Authenticates user.

*

* @param username

* @param password

* @return whether authentication is successful

*/

boolean authenticate(String username, String password);

/**

* Terminates a user's security session.

*/

void logout();

}

AuthenticationServiceAsync:

package com.seewah.sample.gwtspring.client;

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface AuthenticationServiceAsync {

public void authenticate(String username, String password, AsyncCallback callback);

public void logout(AsyncCallback callback);

}

AutoErrorHandlingAsyncCallback:

package com.seewah.sample.gwtspring.client;

import com.google.gwt.user.client.Window;

import com.google.gwt.user.client.rpc.AsyncCallback;

/**

* {@link AsyncCallback} switch recognises {@link ServiceSecurityException} and

* handles it gracefully.

*

*

*

*/

public abstract class AutoErrorHandlingAsyncCallback implements AsyncCallback {

final public void onFailure(Throwable throwable) {

if (throwable instanceof ServiceSecurityException) {

Window.alert("You do not have enough privilege to carry out the operation!");

} else {

Window.alert(throwable.getMessage());

}

}

}

Demo:

package com.seewah.sample.gwtspring.client;

import com.google.gwt.core.client.EntryPoint;

import com.google.gwt.event.dom.client.ClickEvent;

import com.google.gwt.event.dom.client.ClickHandler;

import com.google.gwt.user.client.Window;

import com.google.gwt.user.client.ui.Button;

import com.google.gwt.user.client.ui.HTML;

import com.google.gwt.user.client.ui.HorizontalPanel;

import com.google.gwt.user.client.ui.Hyperlink;

import com.google.gwt.user.client.ui.Label;

import com.google.gwt.user.client.ui.RootPanel;

import com.google.gwt.user.client.ui.VerticalPanel;

/**

* GWT Spring Security demo entry point.

*

*

*

*/

public class Demo implements EntryPoint, ClickHandler {

private Button loginBtn;

private Button logoutBtn;

private Label loginStatus;

private Hyperlink publicOp;

private Hyperlink protectedOp;

private AuthenticationServiceAsync authenticationServiceAsync;

private DocumentServiceAsync documentServiceAsync;

@SuppressWarnings("deprecation")

public void onModuleLoad() {

authenticationServiceAsync = AuthenticationService.Util.getInstance();

documentServiceAsync = DocumentService.Util.getInstance();

VerticalPanel outerPanel = new VerticalPanel();

HorizontalPanel loginPanel = new HorizontalPanel();

outerPanel.add(loginPanel);

loginBtn = new Button("LOG IN");

loginBtn.addClickHandler(this);

logoutBtn = new Button("LOG OUT");

logoutBtn.addClickHandler(this);

loginStatus = new Label("your are currently NOT LOGGED IN");

loginPanel.add(loginBtn);

loginPanel.add(logoutBtn);

loginPanel.add(loginStatus);

outerPanel.add(new HTML("
"));

publicOp = new Hyperlink("Get number of public publications", "");

publicOp.addClickHandler(this);

outerPanel.add(publicOp);

protectedOp = new Hyperlink("Get number of private publications", "");

protectedOp.addClickHandler(this);

outerPanel.add(protectedOp);

RootPanel.get("container").add(outerPanel);

}

public void onClick(ClickEvent event) {

Object sender = event.getSource();

if (sender == loginBtn) {

// service does not require username and password for this demo

authenticationServiceAsync.authenticate("", "", new AutoErrorHandlingAsyncCallback() {

public void onSuccess(Boolean result) {

if (result) {

loginStatus.setText("your are currently LOGGED IN");

} else {

loginStatus.setText("your are currently NOT LOGGED IN");

}

}

});

} else if (sender == logoutBtn) {

authenticationServiceAsync.logout(new AutoErrorHandlingAsyncCallback() {

public void onSuccess(Object result) {

loginStatus.setText("your are currently NOT LOGGED IN");

}

});

} else if (sender == publicOp) {

documentServiceAsync.getNumberOfPublicPublications(new AutoErrorHandlingAsyncCallback() {

public void onSuccess(Integer result) {

Window.alert(result.toString());

}

});

} else if (sender == protectedOp) {

documentServiceAsync.getNumberOfPrivatePublications(new AutoErrorHandlingAsyncCallback() {

public void onSuccess(Integer result) {

Window.alert(result.toString());

}

});

}

}

}

DocumentService:

package com.seewah.sample.gwtspring.client;

import com.google.gwt.core.client.GWT;

import com.google.gwt.user.client.rpc.RemoteService;

import com.google.gwt.user.client.rpc.ServiceDefTarget;

/**

* Document service.

*

*

*

*/

public interface DocumentService extends RemoteService {

public static final String SERVICE_URI = "documentService";

public static class Util {

public static DocumentServiceAsync getInstance() {

DocumentServiceAsync instance = (DocumentServiceAsync) GWT.create(DocumentService.class);

ServiceDefTarget target = (ServiceDefTarget) instance;

target.setServiceEntryPoint(GWT.getModuleBaseURL() + SERVICE_URI);

return instance;

}

}

/**

* Returns the number of public publications.

*

* @return

*/

int getNumberOfPublicPublications();

/**

* Returns the number of private publications.

*

* @return

* @exception ServiceSecurityException

*/

int getNumberOfPrivatePublications() throws ServiceSecurityException;

}

DocumentServiceAsync:

package com.seewah.sample.gwtspring.client;

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface DocumentServiceAsync {

public void getNumberOfPublicPublications(AsyncCallback callback);

public void getNumberOfPrivatePublications(AsyncCallback callback);

}

ServiceSecurityException:

package com.seewah.sample.gwtspring.client;

@SuppressWarnings("serial")

public class ServiceSecurityException extends Exception {

}

DummyAuthenticationProvider:

package com.seewah.sample.gwtspring.server.security;

import org.springframework.security.core.Authentication;

import org.springframework.security.core.AuthenticationException;

import org.springframework.security.authentication.AuthenticationProvider;

/**

* A dummy {@link AuthenticationProvider} implementation.

*

*

* @created 6 Jan 2009

*/

public class DummyAuthenticationProvider implements AuthenticationProvider {

public Authentication authenticate(Authentication authentication) throws AuthenticationException {

throw new IllegalStateException("This implementation is a dummy class, created purely so that "

+ "spring security namespace tags can be used in application context, and this method should "

+ "never be called");

}

@SuppressWarnings("rawtypes")

public boolean supports(Class clazz) {

throw new IllegalStateException("This implementation is a dummy class, created purely so that "

+ "spring security namespace tags can be used in application context, and this method should "

+ "never be called");

}

}

DummyEntryPoint:

package com.seewah.sample.gwtspring.server.security;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.AuthenticationException;

import org.springframework.security.web.AuthenticationEntryPoint;

/**

* A dummy {@link AuthenticationEntryPoint} implementation.

*

*

* @created 6 Jan 2009

*/

public class DummyEntryPoint implements AuthenticationEntryPoint {

@Override

public void commence(HttpServletRequest arg0, HttpServletResponse arg1,

AuthenticationException arg2) throws IOException, ServletException {

throw new IllegalStateException("This implementation is a dummy class, created purely so that "

+ "spring security namespace tags can be used in application context, and this method should "

+ "never be called");

}

}

AuthenticationService:

package com.seewah.sample.gwtspring.server.service;

/**

* "Spring managed" service layer interface for authentication service.

*

*

*

*/

public interface AuthenticationService {

/**

* Authenticates user.

*

* @param username

* @param password

* @return whether authentication is successful

*/

boolean authenticate(String username, String password);

/**

* Terminates a user's security session.

*/

void logout();

}

AuthenticationServiceImpl:

package com.seewah.sample.gwtspring.server.service;

import java.util.Arrays;

import org.springframework.security.core.Authentication;

import org.springframework.security.core.GrantedAuthority;

import org.springframework.security.core.authority.GrantedAuthorityImpl;

import org.springframework.security.core.context.SecurityContext;

import org.springframework.security.core.context.SecurityContextHolder;

import org.springframework.security.core.context.SecurityContextImpl;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import org.springframework.security.core.userdetails.User;

/**

* {@link AuthenticationService} implementation.

*

*

*

*/

public class AuthenticationServiceImpl implements AuthenticationService {

public boolean authenticate(String username, String password) {

// creating an authenticated user token for demo

// regardless of username and password values

GrantedAuthority[] authorities = new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_ADMIN") };

User user = new User("xxx", "yyy", true, true, true, true, Arrays.asList(authorities));

Authentication auth = new UsernamePasswordAuthenticationToken(user, password, Arrays.asList(authorities));

SecurityContext sc = new SecurityContextImpl();

sc.setAuthentication(auth);

SecurityContextHolder.setContext(sc);

return true;

}

public void logout() {

SecurityContextHolder.clearContext();

}

}

DocumentService:

package com.seewah.sample.gwtspring.server.service;

/**

* "Spring managed" service layer interface for document service.

*

*

*

*/

public interface DocumentService {

/**

* Returns the number of public publications.

*

* @return

*/

int getNumberOfPublicPublications();

/**

* Returns the number of private publications.

*

* @return

*/

int getNumberOfPrivatePublications();

}

DocumentServiceImpl:

package com.seewah.sample.gwtspring.server.service;

import org.springframework.beans.factory.annotation.Required;

import org.springframework.security.access.annotation.Secured;

/**

* {@link DocumentService} implementation.

*

*

*

*/

public class DocumentServiceImpl implements DocumentService {

private int privatePublicationCount;

private int publicPublicationCount;

@Required

public void setPrivatePublicationCount(int privatePublicationCount) {

this.privatePublicationCount = privatePublicationCount;

}

@Required

public void setPublicPublicationCount(int publicPublicationCount) {

this.publicPublicationCount = publicPublicationCount;

}

@Secured("ROLE_ADMIN")

public int getNumberOfPrivatePublications() {

return privatePublicationCount;

}

public int getNumberOfPublicPublications() {

return publicPublicationCount;

}

}

AuthenticationServiceServlet:

package com.seewah.sample.gwtspring.server;

import org.springframework.beans.factory.annotation.Autowired;

import com.seewah.sample.gwtspring.client.AuthenticationService;

/**

* {@link AuthenticationService} implementation.

*

*

*

*/

@SuppressWarnings("serial")

public class AuthenticationServiceServlet extends DependencyInjectionRemoteServiceServlet implements

AuthenticationService {

@Autowired

com.seewah.sample.gwtspring.server.service.AuthenticationServiceImpl authenticationService;

public boolean authenticate(String username, String password) {

return authenticationService.authenticate(username, password);

}

public void logout() {

authenticationService.logout();

}

}

DependencyInjectionRemoteServiceServlet:

package com.seewah.sample.gwtspring.server;

import java.lang.reflect.Field;

import java.util.HashSet;

import java.util.Set;

import javax.servlet.ServletException;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.context.support.WebApplicationContextUtils;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**

* {@link RemoteServiceServlet} that automatically injects IoC dependency.

* "org.springframework.beans.factory.annotation.Autowired" annotation is used

* for marking which fields to inject into.

Note that the current

* implementation will only inject "declared" fields, and not inherited fields.

* Fields can be private, protected, package or public.

*

*

* @created 27 Jun 2008

*/

@SuppressWarnings("serial")

public class DependencyInjectionRemoteServiceServlet extends RemoteServiceServlet {

@Override

public void init() throws ServletException {

super.init();

doDependencyInjection();

}

/**

* Carries out dependency injection. This implementation uses Spring IoC

* container.

*

* @exception NoSuchBeanDefinitionException

* if a suitable bean cannot be found in the Spring

* application context. The current implementation looks up

* beans by name

*/

protected void doDependencyInjection() {

for (Field field : getFieldsToDependencyInject()) {

try {

boolean isFieldAccessible = field.isAccessible();

if (!isFieldAccessible) {

field.setAccessible(true);

}

field.set(this, WebApplicationContextUtils.getWebApplicationContext(getServletContext()).getBean(field.getName()));

if (!isFieldAccessible) {

field.setAccessible(false);

}

} catch (IllegalArgumentException e) {

throw new RuntimeException(e);

} catch (IllegalAccessException e) {

throw new RuntimeException(e);

}

}

}

/**

* Find annotated fields to inject.

*

* @return a list of all the annotated fields

*/

private Set getFieldsToDependencyInject() {

Set fieldsToInject = new HashSet();

Field[] fields = this.getClass().getDeclaredFields();

for (Field field : fields) {

if (field.getAnnotation(Autowired.class) != null) {

fieldsToInject.add(field);

}

}

return fieldsToInject;

}

}

DocumentServiceServlet:

package com.seewah.sample.gwtspring.server;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.access.AccessDeniedException;

import com.seewah.sample.gwtspring.client.DocumentService;

import com.seewah.sample.gwtspring.client.ServiceSecurityException;

@SuppressWarnings("serial")

public class DocumentServiceServlet extends DependencyInjectionRemoteServiceServlet implements DocumentService {

@Autowired

com.seewah.sample.gwtspring.server.service.DocumentService documentService;

public int getNumberOfPrivatePublications() throws ServiceSecurityException {

try {

return documentService.getNumberOfPrivatePublications();

} catch (AccessDeniedException e) {

throw new ServiceSecurityException();

}

}

public int getNumberOfPublicPublications() {

return documentService.getNumberOfPublicPublications();

}

}

gwtspring.gwt.xml:

applicationContext-security.xml:

xmlns:security="http://www.springframework.org/schema/security"

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

create-session="always" />

class="com.seewah.sample.gwtspring.server.security.DummyEntryPoint" />

class="com.seewah.sample.gwtspring.server.security.DummyAuthenticationProvider">

class="org.springframework.security.authentication.ProviderManager">

secured-annotations="enabled" jsr250-annotations="disabled" />

applicationContext.xml:

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

class="com.seewah.sample.gwtspring.server.service.AuthenticationServiceImpl" />

class="com.seewah.sample.gwtspring.server.service.DocumentServiceImpl">

1

100

web.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">


gwtspring.html


GoogleAssist: GWT + Spring Security, GWT with Spring Security Example, How to integrate Spring Security with GWT Technology

GWT Spring Security integration demo