https://www.byteslounge.com/tutorials/jaas-authentication-in-tomcat-example
Introduction
Tomcat provides a default JAAS Realm implementation so developers may implement JAAS Login Modules and easily integrate them with the container. In this tutorial we will implement all the required components to put JAAS up and running in Tomcat web container.
This tutorial considers the following software and environment:
- Ubuntu 12.04
- JDK 1.7.0.09
- Tomcat 7.0.35
The Principals
One of the core concepts of JAAS is the existence of users and roles (roles are similar to groups in UNIX systems). Authorization may be issued to specific users or to roles. In JAAS this is concept is translated to Principals: Principals may represent users or roles independently. Let's define User and Role Principals to be used in this example:
package com.byteslounge.jaas;import java.security.Principal;publicclassUserPrincipalimplementsPrincipal{privateString name;publicUserPrincipal(String name){super();this.name = name;}publicvoid setName(String name){this.name = name;}@OverridepublicString getName(){return name;}}
package com.byteslounge.jaas;import java.security.Principal;publicclassRolePrincipalimplementsPrincipal{privateString name;publicRolePrincipal(String name){super();this.name = name;}publicvoid setName(String name){this.name = name;}@OverridepublicString getName(){return name;}}
Basically we are defining two simple Principals, each one of them requiring just a name so they may be promptly identified (a username or a role name). Remember that our principals must implement the java.security.Principal interface.
The Login Module
Now we need to define a Login Module that will actually implement the authentication process. The Login module must implement the javax.security.auth.spi.LoginModule interface:
package com.byteslounge.jaas;import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.Map;import javax.security.auth.Subject;import javax.security.auth.callback.Callback;import javax.security.auth.callback.CallbackHandler;import javax.security.auth.callback.NameCallback;import javax.security.auth.callback.PasswordCallback;import javax.security.auth.callback.UnsupportedCallbackException;import javax.security.auth.login.LoginException;import javax.security.auth.spi.LoginModule;publicclassBytesLoungeLoginModuleimplementsLoginModule{privateCallbackHandler handler;privateSubject subject;privateUserPrincipal userPrincipal;privateRolePrincipal rolePrincipal;privateString login;privateList<String> userGroups;@Overridepublicvoid initialize(Subject subject,CallbackHandler callbackHandler,Map<String,?> sharedState,Map<String,?> options){ handler = callbackHandler;this.subject = subject;}@Overridepublicboolean login()throwsLoginException{Callback[] callbacks =newCallback[2]; callbacks[0]=newNameCallback("login"); callbacks[1]=newPasswordCallback("password",true);try{ handler.handle(callbacks);String name =((NameCallback) callbacks[0]).getName();String password =String.valueOf(((PasswordCallback) callbacks[1]).getPassword());// Here we validate the credentials against some// authentication/authorization provider.// It can be a Database, an external LDAP, // a Web Service, etc.// For this tutorial we are just checking if // user is "user123" and password is "pass123"if(name !=null&& name.equals("user123")&& password !=null&& password.equals("pass123")){// We store the username and roles// fetched from the credentials provider// to be used later in commit() method.// For this tutorial we hard coded the// "admin" role login = name; userGroups =newArrayList<String>(); userGroups.add("admin");returntrue;}// If credentials are NOT OK we throw a LoginExceptionthrownewLoginException("Authentication failed");}catch(IOException e){thrownewLoginException(e.getMessage());}catch(UnsupportedCallbackException e){thrownewLoginException(e.getMessage());}}@Overridepublicboolean commit()throwsLoginException{ userPrincipal =newUserPrincipal(login); subject.getPrincipals().add(userPrincipal);if(userGroups !=null&& userGroups.size()>0){for(String groupName : userGroups){ rolePrincipal =newRolePrincipal(groupName); subject.getPrincipals().add(rolePrincipal);}}returntrue;}@Overridepublicboolean abort()throwsLoginException{returnfalse;}@Overridepublicboolean logout()throwsLoginException{ subject.getPrincipals().remove(userPrincipal); subject.getPrincipals().remove(rolePrincipal);returntrue;}}
All the implemented methods are inherited from javax.security.auth.spi.LoginModule interface and will be called by Tomcat at specific moments during the authentication process.
The login method is responsible for checking if the credentials provided by the end user are valid. This check is made against any kind of authorization entity: It may be a database, a web service, a LDAP, etc. The developer may implement this credentials check in the way required by some specific use case.
Note: The login method must throw a LoginException in case of authentication failure.
In the presence of a successful authentication it should fetch the roles associated with the authenticating user. In this case we simulated and hard coded the admin role as a fetched role from the credentials provider for the current user.
The commit method is called after a successful login method execution and is responsible to store the user and roles obtained by the login method in the respective Subject and in the form of Principals. As you can see in the above module implementation, during the login method execution the credentials are obtained by the means of a callback. This callback is initialized in the initialize method together with Subject initialization.
The logout method is called when the user logs out of the system (and the application implements a logout mechanism). Finally the abort method is called when the login method fails to authenticate the user (throws a LoginException).
The web application
In this example we will secure a specific folder of a Java web application. The application will be very simple and its structure is the following:
We will be securing the admin folder.
To accomplish this task we must define some configuration elements in web.xml file. These entries go directly under the web-app element:
<security-constraint><web-resource-collection><web-resource-name>Admin</web-resource-name><url-pattern>/admin/*</url-pattern></web-resource-collection><auth-constraint><role-name>admin</role-name></auth-constraint></security-constraint><security-role><role-name>admin</role-name></security-role><login-config><auth-method>BASIC</auth-method><realm-name>Admin</realm-name></login-config>
In security-constraint element we are defining that all resources under /admin folder are protected and only the admin role is granted to access the resources. All existing roles must be also defined in the security-role element. The login-config element defines how the credentials will be asked to the end user. In this example we will use the Basic authentication scheme (you may have different mechanisms like presenting a web form or page to the end user, but that will be covered in other tutorial).
Now we must define a new file named context.xml and place it under:
/META-INF/context.xml
<?xml version="1.0" encoding="UTF-8"?><Context><RealmclassName="org.apache.catalina.realm.JAASRealm"appName="BytesLoungeLogin"userClassNames="com.byteslounge.jaas.UserPrincipal"roleClassNames="com.byteslounge.jaas.RolePrincipal"/></Context>
Here we define the class that will implement the JAAS realm. We are using Tomcat default implementation: org.apache.catalina.realm.JAASRealm. We also define which classes will implement the user and roles Principals and we set them to be the ones we defined earlier in this tutorial (UserPrincipal and RolePrincipal). The attribute appName defines how the application will be globally identified by Tomcat in what matters to security configuration.
Finally we must define a JAAS configuration file. We will name it jaas.config and we will place it in Tomcat conf folder:
$CATALINA_BASE/conf/jaas.config
The file looks like the following:
BytesLoungeLogin{ com.byteslounge.jaas.BytesLoungeLoginModule required debug=true;};
This file defines the authentication configuration for BytesLoungeLogin application. Note that it's the same name we used in appName inside context.xml file just above.
Launching Tomcat and testing
Now lets launch Tomcat. We must set a JVM argument that tells Tomcat where the application configuration security file is located, the jaas.config file:
You may set this in the startup catalina.sh file.
When the server is up and running and we access the secure resource:
We will see the Basic authentication dialog asking for credentials:
Now we insert the credentials we hard coded in our Login Module. Username: user123 and Password: pass123
We will be presented the secure resource. Access was granted.
The tutorial full source code is available for download at the end of this page.
Logout process
For more information about the user logout process please refer to the following article:
Keep in mind that this tutorial covered BASIC authentication so your browser will store the user credentials until it's closed.
This means that even if you logout the user, as soon a new request is made against a protected resource the browser will send the credentials again and automatically authenticate the user.
If you need to definitely logout the user and force the credentials to be inserted again you should look into form based authentication: JAAS form based authentication in Tomcat example
相关推荐
**Java Authentication and Authorization Service (JAAS) 认证在Mac版Tomcat中的应用** Java Authentication and Authorization Service (JAAS) 是Java平台的核心组件,用于提供安全的用户认证和权限管理。在Mac版...
**Java Authentication and Authorization Service (JAAS) 深入解析** JAAS,全称为Java Authentication and Authorization Service,是Java平台中的一个核心组件,用于处理应用系统的用户身份验证和权限授权。这个...
tomcat下jaas配置实例(文档有不完善的地方) 1、需要修改 bin\startup.bat(根据自己的环境修改) SET JAVA_HOME=C:\programs\Java\jdk1.8.0_211 SET TOMCAT_HOME=C:\programs\apache-tomcat-5.5.20 2、需要修改 bin...
《JAAS in Action》这本书是Java Authentication and Authorization Service(JAAS)的一个深入解析与实践指南。JAAS是Java平台提供的一种安全框架,用于管理和验证用户身份以及控制对系统资源的访问。下面,我们将...
- **Servlet容器支持**:大多数现代Servlet容器如Tomcat、Jetty都内置了对JAAS的支持,可以通过容器配置进行集成。 - **Web.xml配置**:在Web应用的部署描述符中,可以配置安全管理器,指定使用哪个JAAS Realm进行...
**Java Authentication and Authorization Service (JAAS) 在Web应用程序中的应用** ...通过阅读《JAAS in Action》系列的第9部分,你可以获得更深入的理解,并学习如何在实际项目中有效地利用JAAS。
Java Authentication and Authorization Service (JAAS) 是Java平台中用于实现安全认证和授权的核心框架。它为开发者提供了一种标准化的方法来处理用户身份验证和权限控制,使得应用程序能够根据用户的身份和角色来...
JAAS, the Java Authentication and Authorization Service, has been a standard part of the Java security framework since version 1.4 version and was available as an optional package in J2SE 1.3. Before ...
《JAAS in Action》是一本专注于Java Authentication and Authorization Service(JAAS)的书籍,它深入探讨了Java平台上的安全机制。JAAS是Java提供的一种框架,用于管理应用程序的用户身份验证和授权。这本书的...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全认证和授权的核心组件。它为开发者提供了一种标准的方式来管理用户的身份验证和访问控制,从而确保应用程序的安全性。在本精讲中,我们...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全认证和授权的核心组件。它为开发者提供了一种标准的方式来实现用户身份验证和访问控制,从而确保应用程序的安全性。"Jaas in Action"这...
Java Authentication and Authorization Service (JAAS) 是Java平台提供的一种安全框架,用于实现用户身份验证和权限管理。这个框架使得开发者可以轻松地在Java应用程序中集成安全性,而不必深入理解底层的复杂安全...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于实现用户认证和权限授权的一个核心组件。它为开发者提供了一种灵活的方式来实现安全控制,确保只有经过验证和授权的用户能够访问敏感资源或...
Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全性的框架,主要用于用户身份验证和权限授权。在Java应用程序中,尤其是服务器端应用,确保只有合法的用户能够访问资源是至关重要的。...
`i`和`j-sec2`可能是文档或示例项目的部分,它们可能提供了关于如何配置和使用JAAS的详细指南,或者展示了如何将JAAS集成到具体的应用服务器如Tomcat或JBoss中的实例。 学习JAAS对于任何希望构建安全Java应用程序的...
此外,5.5版本还引入了更强大的安全管理模型,如基于角色的访问控制(RBAC),并加强了与Java Authentication and Authorization Service (JAAS)的集成,使得身份验证和授权更为灵活。5.5版本还改进了连接器模块,...
Java Authentication and Authorization Service (JAAS) 是 Java 平台中用于安全管理的重要组件,它提供了一种框架,使得应用程序可以进行用户身份验证和权限控制。在本文中,我们将深入探讨 JAAS 的核心概念、工作...
**Java Authentication and Authorization Service(JAAS)** 是Java平台提供的一个强大的安全框架,用于实现用户身份验证和授权服务。随着服务导向架构(SOA)逐渐从概念阶段向实际应用过渡,那些早期采用者开始...