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人顶

顶 翻译的不错哦!

一个登录配置包括以下信息 :

?
1
2
3
4
5
Name {
       ModuleClass  Flag    ModuleOptions;
       ModuleClass  Flag    ModuleOptions;
       ModuleClass  Flag    ModuleOptions;
 };

一个登录配置中可能包括不只一个的登录模块。

ModuleClass 是登录模块的完整相称类名。Flag 值 ( Required, Requisite, Sufficient, Optional ) 则控制身份验证的行为。

ModuleOptions则直接将值传递给底层登录模块,它的格式是一个用空格分割的列表。

将下列 Tomcat JAAS Realm 配置添加到 Tomcat server.xml 文件中:

?
1
2
3
<realm classname="org.apache.catalina.realm.JAASRealm" appname="jasslogin" userclassnames="com.test.secure.TestUserPrincipal" roleclassnames="com.test.secure.TestRolePrincipal">
  
</realm>

在 tomcat/conf 文件夹中创建 jass.config 文件:

?
1
2
3
jasslogin{
com.test.secure.TestLoginModule  required;
};

在 tomcat/bin 文件夹中创建 setenv.bat 文件,并添加下列配置:

?
1
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 选项。

?
1
boolean login() throws LoginException;

第一个被 LoginContext 调用来实际处理身份验证的方法是 Login 方法,它将返回 true 或 false 。如果验证成功,commit 方法将被调用。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
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(2new 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;
    }
}

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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) 和角色授权的资源访问:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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>

然后添加登录和登录错误页

?
1
FORMjasslogin/join.do/joinerror.do

红薯
翻译于 3年前

0人顶

顶 翻译的不错哦!

6. 用户密码和角色

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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');

登录表单

?
1
2
3
4
5
6
7
8
9
10
<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 身份验证和授权相关推荐

  1. java验证身份证合法性_Java安全性,第2部分:身份验证和授权

    关于本教程 本教程是关于什么的? 也许没有比应用程序安全更重要的软件工程主题. 攻击是昂贵的,无论是来自内部还是外部,而且某些攻击可能会使软件公司承担赔偿责任. 随着计算机(尤其是Internet)技 ...

  2. iis授权mysql验证_ASP.NET Web API身份验证和授权

    本文是作者所理解和翻译的内容. 这篇文章包括两部分:身份验证和授权. 身份验证用来确定一个用户的身份.例如,Alice用她的用户名和密码登陆系统,服务器用她的用户名和密码来确定她的身份. 授权是判断一 ...

  3. ASP.NET Web API身份验证和授权

    英语原文地址:http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-a ...

  4. .NET6之MiniAPI(九):基于角色的身份验证和授权

    身份验证是这样一个过程:由用户提供凭据,然后将其与存储在操作系统.数据库.应用或资源中的凭据进行比较. 在授权过程中,如果凭据匹配,则用户身份验证成功,可执行已向其授权的操作. 授权指判断允许用户执行 ...

  5. 开源软件加密授权方案_身份验证和授权作为开源解决方案服务

    开源软件加密授权方案 通过实施身份验证和授权(a&a)机制为所有用户数据设计集中式服务. 我将分享我的经验并最终确定解决方案的结论. 该设计包括客户端(Web应用程序)和服务器(A&A ...

  6. 身份验证和授权作为开源解决方案服务

    通过实施身份验证和授权(a&a)机制为所有用户数据设计集中式服务. 我将分享我的经验并最终确定解决方案的结论. 该设计包括客户端(Web应用程序)和服务器(A&A中心). 术语: 1. ...

  7. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第2部分

    目录 介绍 用户角色 如何创建自定义授权特性? AuthorizeAttribute AuthorizeFilter 如何在控制器和操作方法级别设置权限? 检查用户权限的扩展方法 如何在操作方法(内联 ...

  8. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分

    目录 介绍 JWT(JSON Web令牌) ASP.NET Core中的JWToken配置 用户模型类 创建令牌 第1步 第2步 第4步 令牌存储 中间件 自定义中间件app.Use() 中间件app ...

  9. security工作笔记004---.NET Web安全性-身份验证和授权(一)之Principal

    JAVA技术交流QQ群:170933152 1.概述 为了确保应用程序的安全,安全性有几个重要方面需要考虑.一是应用程序的用户,访问应用程序的是一个真正的用户,还是伪装成用户的某个人?如何确定这个用户 ...

  10. 使用kubectl访问Kubernetes集群时的身份验证和授权

    全栈工程师开发手册 (作者:栾鹏) 架构系列文章 kubectl是日常访问和管理Kubernetes集群最为常用的工具. 当我们使用kubeadm成功引导启动(init)一个Kubernetes集群的 ...

最新文章

  1. 【一语点醒梦中人】如何优雅地合并两个JSON对象 → Object.assign(a, b)和Object.assign({}, a, b)的区别
  2. 设计模式系列3-----C++实现命令模式(Command Pattern)
  3. 业界首发丨网易云信虚拟人解决方案,首创客户端+云端双渲染技术
  4. centos6 mysql 导出sql_centos环境下如何导出数据库
  5. 一劳永逸:域名支持通配符,ASP.NET Core中配置CORS
  6. [BUUCTF-pwn]——picoctf_2018_buffer overflow 2
  7. 用Python实现快速排序
  8. jquery页面滚动显示浮动菜单栏锚点定位效果
  9. 【pyqt5学习——信号与槽】实例计时器(解决界面卡顿问题)
  10. java dao 单元测试_Spring Service、Dao进行Junit单元测试
  11. eclipse配置python开发环境_eclipse怎样搭建Python开发环境
  12. 前端npm install失败
  13. 详解 Ops 智能运维机器人,故障处理又快又准!
  14. python描述器descriptor_python装饰器decorator、描述器descriptor
  15. c语言指针教学word,C语言中的指针和指针教学
  16. 沟通CTBS助华盛集团实现财务集中管理
  17. 卡巴斯基离线病毒库升级办法
  18. 【易错点 学习笔记】Solidity语法constant/view/pure
  19. caffe cmake matlab,编译caffe时候抛出的错误
  20. RTSP拉流h265(hevc)+AAC关键节点详解!史上最全RTSP+hevc 交互全记录!

热门文章

  1. python - 求约数 质数法
  2. [转]在WPF中打开网页方法总结
  3. 一个基于verilog的FPGA 的LCD 1602 显示程序
  4. 干货全拿走-用Excel构建股票量化交易模型
  5. PostgreSQL extra_float_digits——控制浮点数精度
  6. Win10系统设置为英文
  7. 在虚拟机中安装Windows XP
  8. AutoCAD2012官方原版软件下载
  9. 宏杉科技引领数据中心全IP化潮流 一站式存储专家优势凸显
  10. 大数据爬虫的一些小目标