文档章节

JAAS authentication in Tomcat example

cyper
 cyper
发布于 2015/03/02 21:04
字数 1355
阅读 15
收藏 0
点赞 0
评论 0
In this tutorial you will learn how to configure JAAS authentication in Tomcat using the HTTP Basic authentication scheme.

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:

  1. Ubuntu 12.04
  2. JDK 1.7.0.09
  3. 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:

User Principal
 package com.byteslounge.jaas; import java.security.Principal; public class UserPrincipal implements Principal { private String name; public UserPrincipal(String name) { super(); this.name = name; } public void setName(String name) { this.name = name; } @Override public String getName() { return name; } } 

Role Principal
 package com.byteslounge.jaas; import java.security.Principal; public class RolePrincipal implements Principal { private String name; public RolePrincipal(String name) { super(); this.name = name; } public void setName(String name) { this.name = name; } @Override public String 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:

Login Module
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; public class BytesLoungeLoginModule implements LoginModule { private CallbackHandler handler; private Subject subject; private UserPrincipal userPrincipal; private RolePrincipal rolePrincipal; private String login; private List<String> userGroups; @Override public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { handler = callbackHandler; this.subject = subject; } @Override public boolean login() throws LoginException { Callback[] callbacks = new Callback[2]; callbacks[0] = new NameCallback("login"); callbacks[1] = new PasswordCallback("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 = new ArrayList<String>(); userGroups.add("admin"); return true; } // If credentials are NOT OK we throw a LoginException throw new LoginException("Authentication failed"); } catch (IOException e) { throw new LoginException(e.getMessage()); } catch (UnsupportedCallbackException e) { throw new LoginException(e.getMessage()); } } @Override public boolean commit() throws LoginException { userPrincipal = new UserPrincipal(login); subject.getPrincipals().add(userPrincipal); if (userGroups != null && userGroups.size() > 0) { for (String groupName : userGroups) { rolePrincipal = new RolePrincipal(groupName); subject.getPrincipals().add(rolePrincipal); } } return true; } @Override public boolean abort() throws LoginException { return false; } @Override public boolean logout() throws LoginException { subject.getPrincipals().remove(userPrincipal); subject.getPrincipals().remove(rolePrincipal); return true; } } 

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:

Application structure
Project folder structure

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 section of web.xml file
 <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

/META-INF/context.xml
 <?xml version="1.0" encoding="UTF-8"?> <Context> <Realm className="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:

jaas.config
 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:

JAVA_OPTS=$JAVA_OPTS "-Djava.security.auth.login.config==$CATALINA_BASE/conf/jaas.config"

You may set this in the startup catalina.sh file.

When the server is up and running and we access the secure resource:

/admin/admin.html

We will see the Basic authentication dialog asking for credentials:

Authentication dialog
Authentication dialog

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.

Access granted
Web application access 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:

JAAS logout example

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

Download source code from this article

Related Articles

本文转载自:http://www.byteslounge.com/tutorials/jaas-authentication-in-tomcat-example

共有 人打赏支持
cyper

cyper

粉丝 58
博文 618
码字总数 143161
作品 0
武汉
前端工程师
Apache Tomcat 7.0.14 发布

Apache Tomcat 团队通过邮件列表发布了 Tomcat 7.0.14 版本(直接跳过7.0.13)。该版本主要是bug修复,还有两个新特性: - new StuckThreadDetectionValve to identify long running request...

红薯 ⋅ 2011/05/13 ⋅ 6

System Dependencies

Dependencies with the scope system are always available and are not looked up in repository. They are usually used to tell Maven about dependencies which are provided by the JDK......

Geek-S ⋅ 2016/03/02 ⋅ 0

Build RESTful APIs with Spring MVC:Security

Secures APIs We have configured Spring Security in before posts. In this post, I will show you using Spring Security to protect APIs, aka provides Anthentication and Anthorizati......

hantsy ⋅ 2016/07/25 ⋅ 0

Tomcat JAAS 简单的登录

Java Authentication Authorization Service(JAAS,Java验证和授权API)提供了灵活和可伸缩的机制来保证客户端或服务器端的Java程序。[来自百度百科] 登录界面 注意 下面的 name是不可以修改...

Jeremy_pan ⋅ 2015/03/21 ⋅ 0

JOSSO在JBOSS中安装与配置

JOSSO在JBOSS中安装与配置 1、JOSSO单点登录网关 1.1进入josso/bin目录,执行josso-gsh命令 1.2 安装JOSSO的核心Gateway,执行命令 gateway install --target <JBOSSHOME> --jboss-instance ......

今幕明 ⋅ 2014/05/13 ⋅ 0

Liferay额外研究(一):初步在新Tomcat下部署

(一)部署Liferay Portlet Liferay简单部署一个portlet并不是很复杂,通过WEB-INF目录下的portlet.xml、liferay-portlet.xml、liferay-display.xml描述即可。 描述 portlet.xml portlet.xm...

小编辑 ⋅ 2010/04/15 ⋅ 0

Seam安全模块框架--Seam Security

Seam Security 中的验证特性是基于JAAS (Java Authentication and Authorization Service)开发的,它提供了用来进行用户身份认证的高度可配置的接口。然而,针对复杂多变的验证需求,Seam ...

匿名 ⋅ 2010/12/03 ⋅ 0

MyEclispse+tomcat+liferay 安装时遇到的问题。

搭建liferay环境( JDK 1.6 ,Ant 1.7,Tomcat 6.0 ,Myeclipse 8 )完成后启动时提示严重错误 严重 :Class com.liferay.portal.security.jaas.PortalPrincipal not found! Class not added......

more ⋅ 2011/12/15 ⋅ 3

Liferay Portal 的安装

一、 简单安装 1)下载并安装 JDK1.5 1、 下载并安装 Windows Platform J2SE(TM) Development Kit 5.0 Update ,下载网址 http://java.sun.com/j2se/1.5.0/download.jsp 2、 在控制面板 --> ......

小编辑 ⋅ 2010/04/15 ⋅ 3

JMS 之 Active MQ的安全机制

一、认证 认证(Authentication):验证某个实体或者用户是否有权限访问受保护资源。 MQ提供两种插件用于权限认证: (一)、Simple authentication plug-in:直接把相关的权限认证信息配置到...

xsster ⋅ 2017/07/28 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

VS2015配置并运行汇编(一步一步照图做)【vs2017的链接在最后】

x64: TITLE Add and Subtract (AddSub.asm) ; This program adds and subtracts 32-bit integers. ; Last update: 2/1/02 ;.MODEL flat,stdcall x64 not su......

simpower ⋅ 昨天 ⋅ 0

一起读书《深入浅出nodejs》-node模块机制

node 模块机制 前言 说到node,就不免得提到JavaScript。JavaScript自诞生以来,经历了工具类库、组件库、前端框架、前端应用的变迁。通过无数开发人员的努力,JavaScript不断被类聚和抽象,...

小草先森 ⋅ 昨天 ⋅ 0

Java桌球小游戏

其实算不上一个游戏,就是两张图片,不停的重画,改变ball图片的位置。一个左右直线碰撞的,一个有角度碰撞的。 左右直线碰撞 package com.bjsxt.test;import javax.swing.*;import j...

森林之下 ⋅ 昨天 ⋅ 0

你真的明白RPC 吗?一起来探究 RPC 的实质

你真的明白RPC 吗?一起来探究 RPC 的实质 不论你是科班出身还是半路转行,这么优秀的你一定上过小学语文,那么对扩句和缩句你一定不陌生。缩句就是去除各种修饰提炼出一句话的核心,而不失基...

AI9o後 ⋅ 昨天 ⋅ 0

z-index设置失效?

今天碰到了一个问题,就是在给li设置提示框的时候,有用到遮罩效果,本来想把对应的出现在最顶层,可是不管将li设置的z-index值设为多大,li都没有出现在遮罩层之上。 我在网上查了z-index设...

IrisHunag ⋅ 昨天 ⋅ 0

CyclicBarrier、CountDownLatch以及Semaphore使用及其原理分析

CyclicBarrier、CountDownLatch以及Semaphore是Java并发包中几个常用的并发组件,这几个组件特点是功能相识很容易混淆。首先我们分别介绍这几个组件的功能然后再通过实例分析和源码分析其中设...

申文波 ⋅ 昨天 ⋅ 0

Java对象的序列化与反序列化

Java对象的序列化与反序列化

Cobbage ⋅ 昨天 ⋅ 0

Sqoop

1.Sqoop: 《=》 SQL to Hadoop 背景 1)场景:数据在RDBMS中,我们如何使用Hive或者Hadoop来进行数据分析呢? 1) RDBMS ==> Hadoop(广义) 2) Hadoop ==> RDBMS 2)原来可以通过MapReduce I...

GordonNemo ⋅ 昨天 ⋅ 0

全量构建和增量构建的区别

1.全量构建每次更新时都需要更新整个数据集,增量构建只对需要更新的时间范围进行更新,所以计算量会较小。 2.全量构建查询时不需要合并不同Segment,增量构建查询时需要合并不同Segment的结...

无精疯 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部