JOSSO Single Sign-On 1.6 简介

来源:互联网 发布:厦门天心软件怎么样 编辑:程序博客网 时间:2024/05/24 00:56
背景知识:身份认证系统包括:目录服务,验证和授权服务,证书服务,单点登陆服务,系统管理等模块。
JOSSO 是一个纯Java基于J2EE的单点登陆验证框架,主要用来提供集中式的平台无关的用户验证。
JOSSO 主要特色:
1 100% Java,使用了 JAAS,WEB Services/SOAP,EJB, Struts, Servlet/JSP 标准技术;
2 基于JAAS的横跨多个应用程序和主机的单点登陆;
3 可插拔的设计框架允许实现多种验证规则和存储方案 ;
4 可以使用servlet和ejb Security API 提供针对web应用,ejb 的身份认证服务;
5 支持X.509 客户端证书的强验证模式;
6 使用反向代理模块可以创建多层的单点登陆认证,并且使用多种策略可在每层配置不同的验证模式;
7 支持数据库,LDAP ,XML等多种方式的存储用户信息和证书服务;
8 客户端提供php,asp 的API;
9 目前 JBoss 3.2.6 和 Jakarta Tomcat 5.0.27 以上版本支持。
10 基于BSD License。 
-------------配置-----------------------------------

Prerequisites

You should first setup JOSSO for one of the supported platforms such as Tomcat and JBoss. Check the specific Setup HOW-TO corresponding to the platform where JOSSO is going to be installed.

Once you're done with the initial setup make sure that the JOSSO web application is accessible.

Introduction

This How-To will explain how to integrate your Java web application with the JOSSO Single Sign-On.

It will implement a Credential Store, configured for providing authentication information ,like the user password, using JDBC database access.

It will implement an Identity Store, configured for providing identity information, like user roles, using JDBC database access.

Create the user and roles database schema

Optional

If you already have your own database schema, this step is not required. You should instead modify the SQL queries in the josso-gateway-config.xml file so that user and roles can be obtained.
First of all, you must have a database server available that provides a JDBC driver.

Lets assume that you don't have a user and role tables. We must then create 3 tables :

  • JOSSO_USER : contains all the users that will be able to sign-on.
  • JOSSO_ROLE : contains all the roles to which users can be associated.
  • JOSSO_USER_ROLE : contains the roles associated with each user.
  • JOSSO_USER_PROPERTY : contains additional properties of the user, like personal data, etc. .

Lets have a look at the ER Diagram :

The DDL SQL scripts should look like the following :

CREATE TABLE JOSSO_ROLE (
NAME VARCHAR2(16) NOT NULL,
DESCRIPTION VARCHAR2(64) NULL
);

ALTER TABLE JOSSO_ROLE
ADD ( PRIMARY KEY (NAME) ) ;

CREATE TABLE JOSSO_USER (
LOGIN VARCHAR2(16) NOT NULL,
PASSWORD VARCHAR2(20) NOT NULL,
NAME VARCHAR2(64) NULL,
DESCRIPTION VARCHAR2(64) NULL
);

ALTER TABLE JOSSO_USER
ADD ( PRIMARY KEY (LOGIN) ) ;


CREATE TABLE JOSSO_USER_PROPERTY (
LOGIN VARCHAR2(16) NOT NULL,
NAME VARCHAR2(255) NOT NULL,
VALUE VARCHAR2(255) NOT NULL
);

ALTER TABLE JOSSO_USER_PROPERTY
ADD ( PRIMARY KEY (LOGIN, NAME) ) ;

CREATE TABLE JOSSO_USER_ROLE (
LOGIN VARCHAR2(16) NOT NULL,
NAME VARCHAR2(255) NOT NULL
);

ALTER TABLE JOSSO_USER_ROLE
ADD ( PRIMARY KEY (LOGIN, NAME) ) ;

ALTER TABLE JOSSO_USER_PROPERTY
ADD ( FOREIGN KEY (LOGIN)
REFERENCES JOSSO_USER ) ;

ALTER TABLE JOSSO_USER_ROLE
ADD ( FOREIGN KEY (NAME)
REFERENCES JOSSO_ROLE ) ;

ALTER TABLE JOSSO_USER_ROLE
ADD ( FOREIGN KEY (LOGIN)
REFERENCES JOSSO_USER ) ;

Execute this DDL in your database.

Create sample Users and Roles

After you finished creating the database schema, add sample user and role records. These users should be able to sign-on to JOSSO.

We'll create three roles :

  • role1
  • role2
  • role3

We'll create two users and associate them to the created roles :

  • user1: which will be part of the 'role1' and 'role2' roles.
  • user2: which will be part of the 'role3' role.

We'll associate three properties to the two just created users :

  • user.name: which will hold the first name of the user.
  • user.lastName: which will hold the lastname of the user.
  • user.registrationDate: which will hold when the user registred.

Lets look ad the DML script to do this :

INSERT INTO JOSSO_ROLE (NAME,DESCRIPTION) VALUES('role1','The Role1');

INSERT INTO JOSSO_ROLE (NAME,DESCRIPTION) VALUES('role2','The Role2');

INSERT INTO JOSSO_ROLE (NAME,DESCRIPTION) VALUES('role3','The Role3');

INSERT INTO JOSSO_USER (LOGIN,PASSWORD,DESCRIPTION)
VALUES('user1', 'user1pwd', 'The User1');

INSERT INTO JOSSO_USER_ROLE (LOGIN,NAME) VALUES('user1', 'role1');

INSERT INTO JOSSO_USER_ROLE (LOGIN,NAME) VALUES('user1', 'role2');

INSERT INTO JOSSO_USER (LOGIN,PASSWORD,DESCRIPTION)
VALUES('user2', 'user2pwd', 'The User2');

INSERT INTO JOSSO_USER_ROLE (LOGIN,NAME) VALUES('user2', 'role3');

INSERT INTO JOSSO_USER_PROPERTY(LOGIN,NAME,VALUE)
VALUES('user1', 'user.name', 'User1 Name');

INSERT INTO JOSSO_USER_PROPERTY(LOGIN,NAME,VALUE)
VALUES('user1', 'user.lastName', 'User1 Last Name');

INSERT INTO JOSSO_USER_PROPERTY(LOGIN,NAME,VALUE)
VALUES('user1', 'user.registrationDate', 'User1 Registration Date');

INSERT INTO JOSSO_USER_PROPERTY(LOGIN,NAME,VALUE)
VALUES('user2', 'user.name', 'User2 Name');

INSERT INTO JOSSO_USER_PROPERTY(LOGIN,NAME,VALUE)
VALUES('user2', 'user.lastName', 'User2 Last Name');

INSERT INTO JOSSO_USER_PROPERTY(LOGIN,NAME,VALUE)
VALUES('user2', 'user.registrationDate', 'User2 Registration Date');

Configure the SSO Gateway

Now we need to tell the Single Sign-On Gateway how to obtain user and role information in order to authenticate users.

We'll also tell the Single Sign-On Gateway how to load the properties of the user.

Modify the josso-gateway-config.xml configuration file located in the /WEB-INF/classes folder of the JOSSO web application.

Lets look at the josso-gateway.xml configuration file content :

<?xml version="1.0" encoding="ISO-8859-1" ?>
<domain>
<name>SampleDomain</name>
<type>web</type>
<authenticator>
<class>org.josso.auth.AuthenticatorImpl</class>
<authentication-schemes>

<!-- Basic Authentication Scheme -->
<authentication-scheme>
<name>basic-authentication</name>
<class>org.josso.auth.scheme.UsernamePasswordAuthScheme</class>

<!-- ========================================================= -->
<!-- JDBC Credential Store -->
<!-- ========================================================= -->
<credential-store>
<class>
org.josso.gateway.identity.service.store.db.JDBCIdentityStore
</class>
<credentialsQueryString>
SELECT login AS username , password AS password FROM josso_user
WHERE login = ?
</credentialsQueryString>
<connectionName>SCOTT</connectionName>
<connectionPassword>TIGER</connectionPassword>
<connectionURL>jdbc:oracle:thin:@mydbhost:1521:mydb</connectionURL>
<driverName>oracle.jdbc.driver.OracleDriver</driverName>
</credential-store>

<credential-store-key-adapter>
<class>
org.josso.gateway.identity.service.store.SimpleIdentityStoreKeyAdapter
</class>
</credential-store-key-adapter>

</authentication-scheme>

</authentication-schemes>
</authenticator>

<sso-identity-manager>
<class>org.josso.gateway.identity.service.SSOIdentityManagerImpl</class>
<!-- ========================================================= -->
<!-- JDBC Identity Store -->
<!-- ========================================================= -->
<sso-identity-store>
<class>
org.josso.gateway.identity.service.store.db.JDBCIdentityStore
</class>
<userQueryString>
SELECT login FROM josso_user WHERE login = ?
</userQueryString>
<rolesQueryString>
SELECT josso_role.name FROM josso_role , josso_user_role , josso_user
WHERE josso_user.login = ? AND josso_user.login = josso_user_role.login
AND josso_role.name = josso_user_role.name
</rolesQueryString>
<userPropertiesQueryString>
SELECT 'user.description' AS name , description AS value
FROM josso_user WHERE login = ?
UNION
SELECT name AS name , value AS value FROM josso_user_property WHERE login = ?
</userPropertiesQueryString>

<connectionName>SCOTT</connectionName>
<connectionPassword>TIGER</connectionPassword>
<connectionURL>jdbc:oracle:thin:@mydbhost:1521:mydb</connectionURL>
<driverName>oracle.jdbc.driver.OracleDriver</driverName>
</sso-identity-store>

<sso-identity-store-key-adapter>
<class>
org.josso.gateway.identity.service.store.SimpleIdentityStoreKeyAdapter
</class>
</sso-identity-store-key-adapter>
</sso-identity-manager>

<sso-session-manager>
<class>org.josso.gateway.session.service.SSOSessionManagerImpl</class>

<!--
Set the maximum time interval, in minutes, between client requests
before the SSO Service will invalidate the session. A negative time
indicates that the session should never time out.
-->
<maxInactiveInterval>1</maxInactiveInterval>

<sso-session-store>
<class>
org.josso.gateway.session.service.store.MemorySessionStore
</class>
</sso-session-store>

<sso-session-id-generator>
<class>
org.josso.gateway.session.service.SessionIdGeneratorImpl
</class>
<!--
The message digest algorithm to be used when generating session
identifiers. This must be an algorithm supported by the
java.security.MessageDigest class on your platform.

In J2SE 1.4.2 you can check :
Java Cryptography Architecture API Specification & Reference -
Apendix A : Standard Names
Values are : MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512
-->
<algorithm>MD5</algorithm>
</sso-session-id-generator>
</sso-session-manager>

<sso-audit-manager>
<class>org.josso.gateway.audit.service.SSOAuditManagerImpl</class>
<handlers>

<!-- This handler logs all audit trails using Log4J, under the given category -->
<handler>
<class>org.josso.gateway.audit.service.handler.LoggerAuditTrailHandler</class>
<name>LoggerAuditTrailHandler</name>
<category>org.josso.gateway.audit.SSO_AUDIT</category>
</handler>
</handlers>
</sso-audit-manager>

<!-- SSO Event Manager component -->
<sso-event-manager>
<class>org.josso.gateway.event.security.JMXSSOEventManagerImpl</class>
<!--
JMX Name of the EventManager MBean that will send SSO Events as JMX Notifications
The MBean will be registered by the MBeanComponentKeeper.
-->
<oname>josso:type=SSOEventManager</oname>
</sso-event-manager>

</domain>

Make sure you set your specific values for the for the connectionName, connectionPassword, connectionURL and driverName elements according to your database settings.

Do this for both the Credential Store and Identity Manager settings.

Include the database driver in the JOSSO Gateway

Since the SSO Gateway will use the configured driver, in this case the Oracle JDBC Thin Driver, to execute the configured SQL queries, you will need to make this available in the JOSSO Gateway classpath

Go to the JOSSO installation directory and create the /src/webapp/josso/WEB-INF/lib directory.

Copy the Jar file containing the JDBC driver to the JOSSO installation directory, into the /src/webapp/josso/WEB-INF/lib

Rebuild JOSSO to produce a new josso.war file which will include the JDBC driver and deploy it. Follow your platform specific setup guide to perform this operation.

Make your Java web application become a JOSSO Single Sign-On partner application

Configure the JOSSO Agent

The Catalina web container running the partner web application must know how to reach the Single Sign-On Gateway. To allow this the josso-agent-config.xml configuration file must be installed in the $CATALINA_HOME/bin directory in case of using Jakarta Tomcat, or $JBOSS_HOME/bin directory if using JBoss.

Lets look at the josso-agent.xml configuration file content :

<?xml version="1.0" encoding="ISO-8859-1" ?>
<agent>
<class>org.josso.jb32.agent.JBossCatalinaSSOAgent</class>
<gatewayLoginUrl>http://localhost:8080/josso/signon/login.do</gatewayLoginUrl>
<gatewayLogoutUrl>http://localhost:8080/josso/signon/logout.do</gatewayLogoutUrl>
<service-locator>
<class>org.josso.gateway.WebserviceGatewayServiceLocator</class>
<endpoint>localhost:8080</endpoint>
</service-locator>
<partner-apps>
<partner-app>
<context>/partnerapp</context>
</partner-app>
</partner-apps>
</agent>

You should replace localhost with the hostname of the host where the Single Sign-On Gateway is listening.

Remember to add an entry in the $CATALINA_HOME/bin/josso-config.xml file pointing to the josso-agent-config.xml file. If gateway and agent are deployed in the same server the josso-config.xml configuration file should look like this :

<?xml version="1.0" encoding="ISO-8859-1" ?>
<configuration>
<xml fileName="josso-gateway-config.xml"/>
<xml fileName="josso-agent-config.xml"/>
</configuration>

Set up Security Constraints

Web application Security Constraints

A Web application that uses security requires the user to log in in order to access its resources. The user's credentials are verified against a security realm, and once authenticated, the user will have access only to specified resources within the Web application.

Security in a Web application is configured using three elements:

  • The <login-config> element specifies how the user is prompted to log in and the location of the security realm. If this element is present, the user must be authenticated in order to access any resource that is constrained by a <security-constraint> defined in the Web application.
  • A <security-constraint> is used to define the access privileges to a collection of resources via their URL mapping.
  • A <security-role> element represents a group or principal in the realm. This security role name is used in the <security-constraint> element and can be linked to an alternative role name used in servlet code via the <security-role-ref> element.

Lets look at the complete web.xml file of your partner web application :

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<display-name>JOSSO Partner Application</display-name>

<welcome-file-list id="WelcomeFileList">
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<security-constraint>
<!-- Sample Security Constraint -->
<web-resource-collection>

<web-resource-name>protected-resources</web-resource-name>

<url-pattern>/*</url-pattern>

<http-method>HEAD</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>

</web-resource-collection>

<auth-constraint>
<role-name>role1</role-name>
</auth-constraint>

<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>

<login-config>
<auth-method>FORM</auth-method>

<form-login-config>
<form-login-page>/login-redirect.jsp</form-login-page>
<form-error-page>/login-redirect.jsp</form-error-page>
</form-login-config>
</login-config>

<security-role >
<description>The Role1</description>
<role-name>role1</role-name>
</security-role>

</web-app>

Note
In this example we are assuming that the web context of your web application is 'partnerapp'. You will have to 'protect' this context with a Single Sign-On Agent as described in the Configuring section of the Setup HOW-TOs.
This web.xml file specifies that only the users associated with 'role1' can access your partner application.

When a non-authenticated user requires access your partner application, he will be redirected to the '/partnerapp/login-redirect.jsp' page, which will redirect the user to the JOSSO Sign-on form.

Note that the role name specified in the <role-name> element must be a role with an entry in the 'ROLE' database table that will be retrieved by the Single Sign-On Gateway using the SQL SELECT statement specified in the josso-gateway-config.xml file.

EJB Security Constraints

In case you are running JOSSO in the JBoss application server, the authenticated user's identity will be propagated to the EJBs invoked by the partner web application.

JOSSO will also work with EJB 3.0 components so you can use standard J2EE security annotations insted of a deployment descriptor

The security contraints should be declared in the ejb-jar.xml file of the partner EJB components. Lets look at an example of such file :

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
<display-name>Partner Component</display-name>
<enterprise-beans>
<session>
<ejb-name>PartnerComponentEJB</ejb-name>
<home>org.josso.samples.ejb.PartnerComponentHome</home>
<remote>org.josso.samples.ejb.PartnerComponent</remote>
<ejb-class>org.josso.samples.ejb.PartnerComponentEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>

<assembly-descriptor>
<security-role>
<description>Role 1</description>
<role-name>role1</role-name>
</security-role>

<method-permission>
<description>Security attributes for 'PartnerComponenttEJB' methods</description>
<role-name>role1</role-name>
<method>
<ejb-name>PartnerComponentEJB</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>

<container-transaction>
<method>
<ejb-name>PartnerComponentEJB</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>

This file sets security contraints for a 'PartnerComponentEJB' Enterprise Java Bean, allowing only users associated to role 'role1' to invoke its methods.

For the user identity to be propagated to the EJB tier, the jboss.xml file must set java:/jaas/josso as the security domain in the following way :

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

<!DOCTYPE jboss PUBLIC
"-//JBoss//DTD JBOSS 3.0//EN"
"http://www.jboss.org/j2ee/dtd/jboss_3_0.dtd">

<jboss>
<security-domain>java:/jaas/josso</security-domain>

<enterprise-beans>
<session>
<ejb-name>PartnerComponentEJB</ejb-name>
<jndi-name>josso/samples/PartnerComponentEJB</jndi-name>
</session>
</enterprise-beans>
</jboss>

For more information about integrating EJBs to with the Single Sign-On infrastructure you can browse the sample online from our CVS repository here

Create the Redirect Page

When the servlet container detects that the user wishes to access a protected resource, it will redirect him to the /partnerapp/login-redirect.jsp page.

We then need to add a login-redirect.jsp JSP page to our partner web application that must look like this :

<%@page contentType="text/html; charset=iso-8859-1" language="java"
session="true"%>
<%
response.sendRedirect(request.getContextPath() + "/josso_login/");
%>

This JSP page will redirect the user to a special URI which will inform the Single Sign-On Agent to redirect the user to the configured login form in the Single Sign-On Gateway.

To change this URL, modify the <gatewayLoginUrl> element value in the josso-agent-config.xml file.

The partner application must allow the user to logout. This action must be delegated to the Gateway by redirecting the user in the following way :

<%@page contentType="text/html; charset=iso-8859-1" language="java"
session="true" %>
<%
response.sendRedirect(request.getContextPath() + "/josso_logout/");
%>

The Single Sign-On Agent will intercept this request an redirect the user to the configured Url in the <gatewayLogoutUrl> element of the josso-agent-config.xml file.

Build the Partner Application

Build your Partner Application as usual by including the WEB-INF/web.xml with your protected resources set as seen before.

In case of deploying a Partner Application which includes EJB components you should also include the ejb-jar.xml and jboss.xml files.

Deploy the Partner Application

In case of using Jakarta Tomcat, deploy your partner application WAR file in the $CATALINA_HOME/webapp directory.

In case of using JBoss, drop your partner application EAR file in the $JBOSS_HOME/server/default/deploy directory.

Testing it

Contact the Partner application

Using your web browser, contact the following url : *http://localhost:8080/partnerapp/* .

Instead of partnerapp use the web context name of your web application.

You should be redirected to the Gateway Single Sign-On logon form located in the JOSSO Gateway at *http://localhost:8080/josso/signon/login.do*.

Authenticate

When the sign-on form is displayed, logon using one of the user/password pairs previously inserted in the user table. Logon with the user1 user since its associated with the role1 role. This role was set in the web.xml file as authorized to access the partner web application.

On authentication the user will be redirected back to the partner application.

Access the partner application

From the partner application it will be possible, using the standard Servlet Security API, to access the information of the logged user.

Lets see how this can be done :

<%@ page contentType="text/html; charset=iso-8859-1" language="java" %>
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<title>Sample Partner Application - JOSSO</title>
</head>

<body>
<p>This is a very simple JOSSO partner application</p>
<p>Your username is : <b><%=request.getRemoteUser()%></b>&nbsp;
<font color="red">(Retrieved from request.getRemoteUser())</font></p>
</body>
</html>

You should see something like : This is a very simple JOSSO partner application

Your username is : user1 (Retrieved from request.getRemoteUser())

In this example we used as a JSP partner web application. You can protected any java web application (ie: Servlet, Struts, etc.).

Using the Custom User Properties Feature

As seen in the previous sample configuration file, using the <userPropertiesQueryString> element its possible to make the Single Sign-On Gateway include custom user properties to the Principal. Such Principal will then be available to partner web application using the standard Servlet Security API, allowing the partner application to access additional user properties without having to query the resource containing the additional user properties.

These properties are stored in the org.josso.gateway.identity.SSOUser class instance as an array of org.josso.gateway.SSONameValuePair class instances.

To access such properties you will have to cast the User Principal associated with the HttpServletRequest in the following way :

...
<% // Check if we have a principal ...
if (request.getUserPrincipal() != null)
{ %>
<p>Your username is : <b><%=request.getRemoteUser()%></b>&nbsp;
<font color="red">(Retrieved from request.getRemoteUser())</font></p>
<% // Cast the principal to a josso specific user,
//and iterate over its properties.
org.josso.gateway.identity.SSOUser ssoUser =
(org.josso.gateway.identity.SSOUser)
request.getUserPrincipal();
for (int i = 0 ; i < ssoUser.getProperties().length ; i++)
{ %>
<p><%=ssoUser.getProperties()[i].getName()%> :
<%=ssoUser.getProperties()[i].getValue()%> </p>
<% } %>
<% }
...

For more detail, check the sample located in the src/webapp/samples/partnerapp/josso directory of the JOSSO distribution.

Or browse the sample online from our CVS repository here

Note
To use this feature make sure you complete the step described in the 'Add a JAAS Realm' section of the Setup HOW-TOs. The standard Catalina JAASRealm is no longer used, instead a JOSSO JAAS Realm must be used now.

For more information

Check the sample partner application in the JOSSO distribution located in the src/webapp/samples/partnerappdirectory. Browse it online from our SVN repository here.

Comments

Care to comment on this How-To? Help keep this document relevant by passing along any constructive feedback to the josso-docs

原创粉丝点击