Tomcat JAAS 身份验证和授权
来源:互联网 发布:paparecipe正品软件 编辑:程序博客网 时间:2024/05/17 05:06
ava 认证和授权服务(JAAS)是一种用于验证用户身份以确定安全等级的 Tomcat Realm ( org.apache.catalina.Realm)的实现。
需求
Tomcat 7.0, MVC (推荐 Spring MVC)和数据库(推荐 Mysql)1. 配置
appName
appName 属性的值将被传递给 LoginContext (javax.security.auth.login.LoginContext) 构造函数,以指定实现LoginModule ( javax.security.auth.spi.LoginModule) 的实体名称。
LoginModule 是一个提供了特定类型的身份验证的可插拔接口。 LoginContext 通过读取配置(javax.security.auth.login.Configuration) 指定登录程序中的登录模块(S)。
K6F
翻译于 3年前
0人顶
顶 翻译的不错哦!
一个登录配置包括以下信息 :
Name {
ModuleClass Flag ModuleOptions;
ModuleClass Flag ModuleOptions;
ModuleClass Flag ModuleOptions;
};
一个登录配置中可能包括不只一个的登录模块。
ModuleClass 是登录模块的完整相称类名。Flag 值 ( Required, Requisite, Sufficient, Optional ) 则控制身份验证的行为。
ModuleOptions则直接将值传递给底层登录模块,它的格式是一个用空格分割的列表。
将下列 Tomcat JAAS Realm 配置添加到 Tomcat server.xml 文件中:
<
realm
classname
=
"org.apache.catalina.realm.JAASRealm"
appname
=
"jasslogin"
userclassnames
=
"com.test.secure.TestUserPrincipal"
roleclassnames
=
"com.test.secure.TestRolePrincipal"
>
</
realm
>
在 tomcat/conf 文件夹中创建 jass.config 文件:
jasslogin{
com.test.secure.TestLoginModule required;
};
在 tomcat/bin 文件夹中创建 setenv.bat 文件,并添加下列配置:
set JAVA_OPTS=-Djava.security.auth.login.config==C:/tomcat/conf/jaas.config
K6F
翻译于 3年前
0人顶
顶 翻译的不错哦!
其它翻译版本(1)2. 登录模块
当 logincontext 读取配置时,登录模块将初始化,包括 Subject ( javax.security.auth.Subject),回叫处理(javax.security.auth.callback.CallBackHandler),共享登录模块以及 LoginModule-specific 选项。
boolean
login()
throws
LoginException;
第一个被 LoginContext 调用来实际处理身份验证的方法是 Login 方法,它将返回 true 或 false 。如果验证成功,commit 方法将被调用。
package
com.test.secure;
import
java.io.IOException;
import
java.security.Principal;
import
java.sql.Connection;
import
java.sql.DriverManager;
import
java.sql.PreparedStatement;
import
java.sql.ResultSet;
import
java.sql.SQLException;
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;
import
org.apache.log4j.Logger;
public
class
TestLoginModule
implements
LoginModule {
Logger logger = Logger.getLogger(TestLoginModule.
class
);
public
static
String USER_QUERY =
"select user_name from users where user_name=? and user_pass=?"
;
public
static
String ROLE_QUERY =
"select role_name from user_roles where user_name=?"
;
private
Subject subject;
private
CallbackHandler callbackHandler;
private
Map sharedState;
private
Map options;
// configurable option
private
boolean
debug =
false
;
// the authentication status
private
boolean
succeeded =
false
;
private
boolean
commitSucceeded =
false
;
// user credentials
private
String username =
null
;
private
char
[] password =
null
;
// principals
private
TestUserPrincipal testUserPrincipal;
private
TestRolePrincipal testRolePrincipal;
private
TestPasswordPrincipal testPasswordPrincipal;
@Override
public
void
initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this
.subject = subject;
this
.callbackHandler = callbackHandler;
this
.sharedState = sharedState;
this
.options = options;
}
@Override
public
boolean
login()
throws
LoginException {
if
(callbackHandler ==
null
) {
throw
new
LoginException(
"call back handler is null"
);
}
Callback[] callbacks =
new
Callback[
2
];
callbacks[
0
] =
new
NameCallback(
"username"
);
callbacks[
1
] =
new
PasswordCallback(
"password: "
,
false
);
try
{
callbackHandler.handle(callbacks);
username = ((NameCallback) callbacks[
0
]).getName();
password = ((PasswordCallback) callbacks[
1
]).getPassword();
if
(username ==
null
|| password ==
null
) {
throw
new
LoginException(
"Callback handler does not return login data properly"
);
}
logger.info(
" username"
+ username);
logger.info(
"password"
+ password);
// authenticate
if
(isValidUser()) {
succeeded =
true
;
return
true
;
}
}
catch
(IOException e) {
e.printStackTrace();
}
catch
(UnsupportedCallbackException e) {
e.printStackTrace();
}
return
false
;
}
@Override
public
boolean
commit()
throws
LoginException {
logger.info(
"committing..."
);
if
(succeeded ==
false
) {
return
false
;
}
else
{
testUserPrincipal =
new
TestUserPrincipal(username);
if
(!subject.getPrincipals().contains(testUserPrincipal)) {
subject.getPrincipals().add(testUserPrincipal);
}
/* testPasswordPrincipal = new TestPasswordPrincipal(new String(
password));
if (!subject.getPrincipals().contains(testPasswordPrincipal)) {
subject.getPrincipals().add(testPasswordPrincipal);
}
*/
// populate subject with roles.
// strings
List roles = getRoles(testUserPrincipal);
for
(String role : roles) {
testRolePrincipal =
new
TestRolePrincipal(role);
if
(!subject.getPrincipals().contains(testRolePrincipal)) {
subject.getPrincipals().add(testRolePrincipal);
}
}
commitSucceeded =
true
;
logger.info(
"Login subject were successfully populated with principals and roles"
);
logger.info(
"--------------principals"
);
logger.info(subject.getPrincipals());
for
(Principal p: subject.getPrincipals()){
if
(p
instanceof
TestRolePrincipal){
logger.info(
" ROLE: "
+p.getName());
}
}
return
true
;
}
}
@Override
public
boolean
abort()
throws
LoginException {
if
(succeeded ==
false
) {
return
false
;
}
else
if
(succeeded ==
true
&& commitSucceeded ==
false
) {
succeeded =
false
;
username =
null
;
if
(password !=
null
) {
password =
null
;
}
testUserPrincipal =
null
;
}
else
{
logout();
}
return
true
;
}
@Override
public
boolean
logout()
throws
LoginException {
subject.getPrincipals().remove(testUserPrincipal);
succeeded =
false
;
succeeded = commitSucceeded;
username =
null
;
if
(password !=
null
) {
for
(
int
i =
0
; i < password.length; i++) {
password[i] =
' '
;
password =
null
;
}
}
testUserPrincipal =
null
;
return
true
;
}
private
boolean
isValidUser()
throws
LoginException {
Connection connection =
null
;
ResultSet rs =
null
;
PreparedStatement stmt =
null
;
try
{
connection = getConnection();
stmt = connection.prepareStatement(USER_QUERY);
stmt.setString(
1
, username);
stmt.setString(
2
,
new
String(password));
rs = stmt.executeQuery();
if
(rs.next()) {
// User exist with the given user name and
// password.
return
true
;
}
}
catch
(Exception e) {
logger.error(
"Error when loading user from the database "
+ e);
e.printStackTrace();
}
finally
{
try
{
rs.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing result set."
+ e);
}
try
{
stmt.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing statement."
+ e);
}
try
{
connection.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing connection."
+ e);
}
}
return
false
;
}
private
List getRoles(TestUserPrincipal user) {
Connection connection =
null
;
ResultSet rs =
null
;
PreparedStatement stmt =
null
;
List roleList =
new
ArrayList();
try
{
connection = getConnection();
stmt = connection.prepareStatement(ROLE_QUERY);
stmt.setString(
1
, username);
rs = stmt.executeQuery();
while
(rs.next()) {
roleList.add(rs.getString(
"role_name"
));
user.addRole(
new
TestRolePrincipal((rs.getString(
"role_name"
))));
}
}
catch
(Exception e) {
logger.error(
"Error when loading user from the database "
+ e);
e.printStackTrace();
}
finally
{
try
{
rs.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing result set."
+ e);
}
try
{
stmt.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing statement."
+ e);
}
try
{
connection.close();
}
catch
(SQLException e) {
logger.error(
"Error when closing connection."
+ e);
}
}
return
roleList;
}
private
Connection getConnection() {
try
{
Class.forName(
"com.mysql.jdbc.Driver"
);
return
DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test"
,
"root"
,
"password"
);
}
catch
(Exception e) {
e.printStackTrace();
}
return
null
;
}
}
package
com.test.secure;
import
java.security.Principal;
import
java.util.HashSet;
import
java.util.Iterator;
import
java.util.Set;
import
org.apache.catalina.Group;
import
org.apache.catalina.Role;
import
org.apache.catalina.User;
import
org.apache.catalina.UserDatabase;
public
class
TestUserPrincipal
implements
User {
private
String username;
private
Set roles =
new
HashSet();
public
TestUserPrincipal(String u){
this
.username=u;
}
@Override
public
String getName() {
// TODO Auto-generated method stub
return
username;
}
@Override
public
void
addGroup(Group arg0) {
// TODO Auto-generated method stub
}
@Override
public
void
addRole(Role role) {
roles.add(role);
}
@Override
public
String getFullName() {
// TODO Auto-generated method stub
return
username;
}
@Override
public
Iterator getGroups() {
return
null
;
}
@Override
public
String getPassword() {
// TODO Auto-generated method stub
return
null
;
}
@Override
public
Iterator getRoles() {
return
roles.iterator();
}
@Override
public
UserDatabase getUserDatabase() {
// TODO Auto-generated method stub
return
null
;
}
@Override
public
String getUsername() {
// TODO Auto-generated method stub
return
username;
}
@Override
public
boolean
isInGroup(Group arg0) {
// TODO Auto-generated method stub
return
false
;
}
@Override
public
boolean
isInRole(Role role) {
if
(
1
==
1
){
return
true
;
}
if
(!roles.isEmpty()){
Iterator it =roles.iterator();
while
(it.hasNext()){
Role rol =(Role)it.next();
if
(rol.getName()!=
null
&& rol.getName().equals(role.getName())){
return
true
;
}
}
}
return
false
;
}
@Override
public
void
removeGroup(Group arg0) {
// TODO Auto-generated method stub
}
@Override
public
void
removeGroups() {
// TODO Auto-generated method stub
}
@Override
public
void
removeRole(Role arg0) {
// TODO Auto-generated method stub
}
@Override
public
void
removeRoles() {
roles.clear();
}
@Override
public
void
setFullName(String arg0) {
setUsername(username);
}
@Override
public
void
setPassword(String arg0) {
// TODO Auto-generated method stub
}
@Override
public
void
setUsername(String arg0) {
this
.username=arg0;
}
}
package
com.test.secure;
import
java.io.Serializable;
import
java.security.Principal;
import
org.apache.catalina.Role;
import
org.apache.catalina.UserDatabase;
public
class
TestRolePrincipal
implements
Role, Serializable {
private
String roleName;
public
TestRolePrincipal(String name){
this
.roleName=name;
}
@Override
public
String getName() {
// TODO Auto-generated method stub
return
getRolename();
}
@Override
public
String getDescription() {
// TODO Auto-generated method stub
return
" some role"
;
}
@Override
public
String getRolename() {
// TODO Auto-generated method stub
return
roleName;
}
@Override
public
UserDatabase getUserDatabase() {
// TODO Auto-generated method stub
return
null
;
}
@Override
public
void
setDescription(String arg0) {
}
@Override
public
void
setRolename(String arg0) {
roleName =arg0;
}
你需要将 tomcat/lib 中的三个类都封装到 jar 中,一边在启动时加载。
K6F
翻译于 3年前
0人顶
顶 翻译的不错哦!
登录处理器
在这个例子中我们使用的是 Spring MVC,但作为测试,你可使用任何其他的请求处理器,或者只是一个 Servlet:
package
com.test.secure;
import
java.security.Principal;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
javax.servlet.http.HttpSession;
import
org.apache.catalina.Session;
import
org.springframework.web.servlet.ModelAndView;
import
org.springframework.web.servlet.mvc.AbstractController;
public
class
SecureController
extends
AbstractController {
@Override
protected
ModelAndView handleRequestInternal(HttpServletRequest req,
HttpServletResponse res)
throws
Exception {
ModelAndView m =
new
ModelAndView(
"SecureView"
);
return
m;
}
}
5. 安全约束
在 web.xml 中增加一个安全约束 ( org.apache.catalina.deploy. SecurityConstraint) 和角色授权的资源访问:
<
security-constraint
>
<
web-resource-collection
>
<
web-resource-name
>interdit< /
web-resource-name
>
<
url-pattern
>/go/*< /
url-pattern
>
< /
web-resource-collection
>
<
auth-constraint
>
<
description
>tomcat< /
description
>
<
role-name
>tomcat< /
role-name
>
< /
auth-constraint
>
< /
security-constraint
>
然后添加登录和登录错误页
FORMjasslogin/join.do/joinerror.do
红薯
翻译于 3年前
0人顶
顶 翻译的不错哦!
CREATE
TABLE
`users` (
`user_name`
varchar
(15)
NOT
NULL
,
`user_pass`
varchar
(15)
NOT
NULL
,
PRIMARY
KEY
(`user_name`);
INSERT
INTO
`users`
VALUES
(
'admin'
,
'root'
),(
'role1'
,
'root'
),(
'tomcat'
,
'tomcat'
);
CREATE
TABLE
`user_roles` (
`user_name`
varchar
(15)
NOT
NULL
,
`role_name`
varchar
(15)
NOT
NULL
,
PRIMARY
KEY
(`user_name`,`role_name`);
INSERT
INTO
`user_roles`
VALUES
(
'tomcat'
,
'manager-gui'
),(
'tomcat'
,
'manager-jmx'
),(
'tomcat'
,
'manager-script'
),(
'tomcat'
,
'manager-status'
),(
'tomcat'
,
'tomcat'
);
登录表单
<
form
action
=
"<%= response.encodeURL("
j_security_check")="" %="">" method="post">
<
fieldset
>
<
legend
>Login </
legend
>
<
p
><
label
for
=
"name"
>Username</
label
> <
input
name
=
"j_username"
type
=
"text"
></
p
>
<
p
><
label
for
=
"e-mail"
>Password</
label
> <
input
name
=
"j_password"
type
=
"password"
><
br
></
p
>
<
p
class
=
"submit"
><
input
value
=
"Submit"
type
=
"submit"
></
p
>
</
fieldset
>
</
form
>
- Tomcat JAAS 身份验证和授权
- 身份验证和授权
- 身份验证和授权
- 身份验证和授权
- 身份验证和授权
- 身份验证和授权
- shiro身份验证和授权
- jaas的认证和授权基本理解
- Java认证和授权服务 JAAS 之 授权
- asp.net身份验证和授权
- asp.net身份验证和授权
- asp.net身份验证和授权
- ASP.NET身份验证和授权
- asp.net身份验证和授权
- shiro身份验证和授权入门
- Tomcat支持的JAAS和JNDI绑定
- jaas:授权内幕
- 使用JAAS框架和LDAP做验证(Authentication)、授权(Authorization)
- 上传图片生成缩略图
- MemCache 详细解读
- (收藏)正则表达式
- 实习-人生新阶段的开始
- ftp服务
- Tomcat JAAS 身份验证和授权
- 第二周项目三-小试循环
- 我的leetcode每日A题
- Pop Sequence
- 使用Loadrunner11录制FTP协议脚本
- 工厂里的那些事
- 翻硬币
- java中的运算符
- Java内存泄露详解