一 什么是JAAS
Java 认证和授权服务”(Java Authentication and Authorization Service,JAAS)是对 Java 2 SDK 的扩展。
JAAS 可分Authentication和Authorization 。
1) Authentication:认证用户身份。看哪个用户在执行代码。通俗的来说就是哪个用户在执行操作。这个操作可能在某个application或bean或servlet上.
2) Authorization : 授权用户操作。也就是验证用户是否对指定资源有特定访问权限。好比某一用户是否有对指定文件的读取权限。
二 常用接口
CallbackHandler:用去用户信息,用于验证用户身份。
LoginModule:用于验证用户信息。
三 简单Demo
MyCallbackHandler.java
package authentication; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; 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; public class MyCallbackHandler implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for(Callback callback:callbacks){ if(callback instanceof NameCallback){ NameCallback nameCallback=(NameCallback)callback; String prompt=nameCallback.getPrompt(); System.err.print(prompt); nameCallback.setName(new BufferedReader(new InputStreamReader(System.in)).readLine()); } if(callback instanceof PasswordCallback){ PasswordCallback passwordCallback=(PasswordCallback)callback; String prompt=passwordCallback.getPrompt(); System.err.print(prompt); passwordCallback.setPassword(new BufferedReader(new InputStreamReader(System.in)).readLine().toCharArray()); } } } }
SampleLoginModule.java
package authentication; 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.login.LoginException; import javax.security.auth.spi.LoginModule; public class SampleLoginModule implements LoginModule { // initial state private Subject subject; private CallbackHandler callbackHandler; private Map sharedState; private Map options; // configurable option private boolean debug = false; // username and password private String username; private char[] password; public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { this.subject = subject; this.callbackHandler = callbackHandler; this.sharedState = sharedState; this.options = options; // initialize any configured options debug = "true".equalsIgnoreCase((String)options.get("debug")); } public boolean login() throws LoginException { Callback[] callbacks = new Callback[2]; callbacks[0] = new NameCallback("user name: "); callbacks[1] = new PasswordCallback("password: ", false); try { callbackHandler.handle(callbacks); } catch (Exception e) { throw new RuntimeException(e); } username = ((NameCallback)callbacks[0]).getName(); password = ((PasswordCallback)callbacks[1]).getPassword(); if("admin".equals(username)&&"admin".equals(new String(password))){ return true; } return false; } public boolean commit() throws LoginException { System.out.println(" =========== commit =========="); return true; } public boolean abort() throws LoginException { System.out.println(" =========== abort =========="); return true; } @Override public boolean logout() throws LoginException { System.out.println(" =========== logout =========="); return true; } }
SampleAcn.java
package authentication; import javax.security.auth.login.LoginContext; public class SampleAcn { public static void main(String[] args) throws Exception { LoginContext lc = new LoginContext("sample",new MyCallbackHandler()); lc.login(); } }
sample_jaas.config
sample { authentication.SampleLoginModule required debug=true; };
要设置的系统参数 -Djava.security.auth.login.config==src/authentication/sample_jaas.config
Demo认证执行流程:
LoginContext lc = new LoginContext("sample",new MyCallbackHandler());
构造LoginContext
lc.login();
执行认证。因为系统参数设置
-Djava.security.auth.login.config==src/authentication/sample_jaas.config
所以认证配置文件是sample_jaas.config。因为构造LoginContext的时候传入的第一个参数是"sample".
所以在sample_jaas.config中查找名为sample的配置段。及
sample { authentication.SampleLoginModule required debug=true; };
authentication.SampleLoginModule为指定的LoginModule实现。
因为构造LoginContext的时候传入的第二个参数是new MyCallbackHandler。所以MyCallbackHandler用于获取用户认证信息。
所以:在执行lc.login()时,会调用SampleLoginModule的login方法。而SampleLoginModule会通过MyCallbackHandler获取用户的认证信息。如果认证成功则返回true,否则返回false.