diff --git a/pom.xml b/pom.xml index 71e5d21b02..a9ec0513e1 100644 --- a/pom.xml +++ b/pom.xml @@ -636,6 +636,7 @@ webrtc wildfly quarkus-extension + security-jaas diff --git a/security-jaas/jaas-app/pom.xml b/security-jaas/jaas-app/pom.xml new file mode 100644 index 0000000000..0cc068c2de --- /dev/null +++ b/security-jaas/jaas-app/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + + com.baeldung.security.jaas + security-jaas + 1.0-SNAPSHOT + + jaas-app + + + + + maven-jar-plugin + 3.1.2 + + + + true + com.baeldung.security.jaas.JaasApplication + + + + + + + + + + com.baeldung.security.jaas + jaas-login-module + 1.0-SNAPSHOT + provided + + + + \ No newline at end of file diff --git a/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/ConsoleCallbackHandler.java b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/ConsoleCallbackHandler.java new file mode 100644 index 0000000000..c5d7e9f6df --- /dev/null +++ b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/ConsoleCallbackHandler.java @@ -0,0 +1,24 @@ +package com.baeldung.security.jaas.app; + +import javax.security.auth.callback.*; +import java.io.Console; +import java.io.IOException; + +public class ConsoleCallbackHandler implements CallbackHandler { + + @Override + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + Console console = System.console(); + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + NameCallback nameCallback = (NameCallback) callback; + nameCallback.setName(console.readLine(nameCallback.getPrompt())); + } else if (callback instanceof PasswordCallback) { + PasswordCallback passwordCallback = (PasswordCallback) callback; + passwordCallback.setPassword(console.readPassword(passwordCallback.getPrompt())); + } else { + throw new UnsupportedCallbackException(callback); + } + } + } +} diff --git a/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/JaasAuthentication.java b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/JaasAuthentication.java new file mode 100644 index 0000000000..8e519c8854 --- /dev/null +++ b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/JaasAuthentication.java @@ -0,0 +1,13 @@ +package com.baeldung.security.jaas.app; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginException; + +public class JaasAuthentication { + + public static void main(String[] args) throws LoginException { + LoginService loginService = new LoginService(); + Subject subject = loginService.login(); + System.out.println(subject.getPrincipals().iterator().next() + " sucessfully logeed in"); + } +} diff --git a/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/JaasAuthorization.java b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/JaasAuthorization.java new file mode 100644 index 0000000000..27e08bc6ca --- /dev/null +++ b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/JaasAuthorization.java @@ -0,0 +1,17 @@ +package com.baeldung.security.jaas.app; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginException; +import java.security.PrivilegedAction; + +public class JaasAuthorization { + + public static void main(String[] args) throws LoginException { + + LoginService loginService = new LoginService(); + Subject subject = loginService.login(); + + PrivilegedAction privilegedAction = new ResourceAction(); + Subject.doAsPrivileged(subject, privilegedAction, null); + } +} diff --git a/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/LoginService.java b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/LoginService.java new file mode 100644 index 0000000000..8eff76527a --- /dev/null +++ b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/LoginService.java @@ -0,0 +1,14 @@ +package com.baeldung.security.jaas.app; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +public class LoginService { + + public Subject login() throws LoginException { + LoginContext loginContext = new LoginContext("jaasApplication", new ConsoleCallbackHandler()); + loginContext.login(); + return loginContext.getSubject(); + } +} diff --git a/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/ResourceAction.java b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/ResourceAction.java new file mode 100644 index 0000000000..28d13775da --- /dev/null +++ b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/ResourceAction.java @@ -0,0 +1,15 @@ +package com.baeldung.security.jaas.app; + +import java.security.PrivilegedAction; + +public class ResourceAction implements PrivilegedAction { + @Override + public Object run() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new ResourcePermission("test_resource")); + } + System.out.println("I have access to test_resource !"); + return null; + } +} diff --git a/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/ResourcePermission.java b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/ResourcePermission.java new file mode 100644 index 0000000000..c2a94579f2 --- /dev/null +++ b/security-jaas/jaas-app/src/main/java/com/baeldung/security/jaas/app/ResourcePermission.java @@ -0,0 +1,9 @@ +package com.baeldung.security.jaas.app; + +import java.security.BasicPermission; + +public class ResourcePermission extends BasicPermission { + public ResourcePermission(String name) { + super(name); + } +} \ No newline at end of file diff --git a/security-jaas/jaas-login-module/pom.xml b/security-jaas/jaas-login-module/pom.xml new file mode 100644 index 0000000000..371aaf3a8f --- /dev/null +++ b/security-jaas/jaas-login-module/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + + com.baeldung.security.jaas + security-jaas + 1.0-SNAPSHOT + + jaas-login-module + + \ No newline at end of file diff --git a/security-jaas/jaas-login-module/src/main/java/com/baeldung/security/jaas/authentication/InMemoryLoginModule.java b/security-jaas/jaas-login-module/src/main/java/com/baeldung/security/jaas/authentication/InMemoryLoginModule.java new file mode 100644 index 0000000000..4a9051ce81 --- /dev/null +++ b/security-jaas/jaas-login-module/src/main/java/com/baeldung/security/jaas/authentication/InMemoryLoginModule.java @@ -0,0 +1,76 @@ +package com.baeldung.security.jaas.authentication; + +import com.sun.security.auth.UserPrincipal; + +import javax.security.auth.Subject; +import javax.security.auth.callback.*; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; +import java.io.IOException; +import java.security.Principal; +import java.util.Map; + +public class InMemoryLoginModule implements LoginModule { + + private static final String USERNAME = "testuser"; + private static final String PASSWORD = "testpassword"; + + private Subject subject; + private CallbackHandler callbackHandler; + private Map sharedState; + private Map options; + + private String username; + private boolean loginSucceeded = false; + private Principal userPrincipal; + + @Override + public void initialize(Subject subject, + CallbackHandler callbackHandler, + Map sharedState, + Map options) { + this.subject = subject; + this.callbackHandler = callbackHandler; + this.sharedState = sharedState; + this.options = options; + } + + @Override + public boolean login() throws LoginException { + NameCallback nameCallback = new NameCallback("username: "); + PasswordCallback passwordCallback = new PasswordCallback("password: ", false); + try { + callbackHandler.handle(new Callback[]{nameCallback, passwordCallback}); + username = nameCallback.getName(); + String password = new String(passwordCallback.getPassword()); + if (USERNAME.equals(username) && PASSWORD.equals(password)) { + loginSucceeded = true; + } + } catch (IOException | UnsupportedCallbackException e) { + //... + } + return loginSucceeded; + } + + @Override + public boolean commit() throws LoginException { + if (!loginSucceeded) { + return false; + } + userPrincipal = new UserPrincipal(username); + subject.getPrincipals().add(userPrincipal); + return true; + } + + @Override + public boolean abort() throws LoginException { + logout(); + return true; + } + + @Override + public boolean logout() throws LoginException { + subject.getPrincipals().remove(userPrincipal); + return false; + } +} diff --git a/security-jaas/jaas.login.config b/security-jaas/jaas.login.config new file mode 100644 index 0000000000..4b0a64540b --- /dev/null +++ b/security-jaas/jaas.login.config @@ -0,0 +1,3 @@ +jaasApplication { + com.baeldung.security.jaas.authentication.InMemoryLoginModule required debug=true; +}; diff --git a/security-jaas/jaas.policy b/security-jaas/jaas.policy new file mode 100644 index 0000000000..0f5b3cbe33 --- /dev/null +++ b/security-jaas/jaas.policy @@ -0,0 +1,14 @@ +grant codebase "file:./jaas-app/target/jaas-app.jar" { + permission javax.security.auth.AuthPermission "createLoginContext.jaasApplication"; + permission javax.security.auth.AuthPermission "doAsPrivileged"; + permission java.lang.RuntimePermission "readFileDescriptor"; + permission java.lang.RuntimePermission "writeFileDescriptor"; +}; + +grant codebase "file:./jaas-login-module/target/jaas-login-module.jar" { + permission javax.security.auth.AuthPermission "modifyPrincipals"; +}; + +grant principal com.sun.security.auth.UserPrincipal "testuser" { + permission com.baeldung.security.jaas.app.ResourcePermission "test_resource"; +}; diff --git a/security-jaas/pom.xml b/security-jaas/pom.xml new file mode 100644 index 0000000000..1e256d4668 --- /dev/null +++ b/security-jaas/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + com.baeldung.security.jaas + security-jaas + 1.0-SNAPSHOT + pom + + + 1.8 + 1.8 + UTF-8 + + + + jaas-app + jaas-login-module + + + + ${project.artifactId} + + + \ No newline at end of file diff --git a/security-jaas/run-authentication.bat b/security-jaas/run-authentication.bat new file mode 100644 index 0000000000..1ee2c2398a --- /dev/null +++ b/security-jaas/run-authentication.bat @@ -0,0 +1 @@ +java -Djava.security.auth.login.config=jaas.login.config -classpath jaas-app/target/jaas-app.jar;jaas-login-module/target/jaas-login-module.jar com.baeldung.security.jaas.app.JaasAuthentication \ No newline at end of file diff --git a/security-jaas/run-authorization.bat b/security-jaas/run-authorization.bat new file mode 100644 index 0000000000..fdb1501ff4 --- /dev/null +++ b/security-jaas/run-authorization.bat @@ -0,0 +1 @@ +java -Djava.security.manager -Djava.security.policy=jaas.policy -Djava.security.auth.login.config=jaas.login.config -classpath %JAVA_HOME%\lib;jaas-app/target/jaas-app.jar;jaas-login-module/target/jaas-login-module.jar com.baeldung.security.jaas.app.JaasAuthorization \ No newline at end of file