生活随笔
收集整理的這篇文章主要介紹了
Tomcat JAAS 身份验证和授权
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
| 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(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; ????} } | ? | 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 身份验证和授权的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。