Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/security/auth/login/LoginContext/CustomLoginModule.java
38860 views
/*1* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.IOException;24import java.security.Principal;25import java.util.Arrays;26import java.util.Locale;27import java.util.Map;28import javax.security.auth.Subject;29import javax.security.auth.callback.Callback;30import javax.security.auth.callback.CallbackHandler;31import javax.security.auth.callback.ChoiceCallback;32import javax.security.auth.callback.ConfirmationCallback;33import javax.security.auth.callback.LanguageCallback;34import javax.security.auth.callback.NameCallback;35import javax.security.auth.callback.PasswordCallback;36import javax.security.auth.callback.TextInputCallback;37import javax.security.auth.callback.TextOutputCallback;38import javax.security.auth.callback.UnsupportedCallbackException;39import javax.security.auth.login.FailedLoginException;40import javax.security.auth.login.LoginException;41import javax.security.auth.spi.LoginModule;4243public class CustomLoginModule implements LoginModule {4445static final String HELLO = "Hello";4647private Subject subject;48private CallbackHandler callbackHandler;49private boolean loginSucceeded = false;50private String username;51private char[] password;5253/*54* Initialize this LoginModule.55*/56@Override57public void initialize(Subject subject, CallbackHandler callbackHandler,58Map<String, ?> sharedState, Map<String, ?> options) {59this.subject = subject;60this.callbackHandler = callbackHandler;6162// check if custom parameter is passed from comfiguration63if (options == null) {64throw new RuntimeException("options is null");65}6667// read username/password from configuration68Object o = options.get("username");69if (o == null) {70throw new RuntimeException("Custom parameter not passed");71}72if (!(o instanceof String)) {73throw new RuntimeException("Password is not a string");74}75username = (String) o;7677o = options.get("password");78if (o == null) {79throw new RuntimeException("Custom parameter not passed");80}81if (!(o instanceof String)) {82throw new RuntimeException("Password is not a string");83}84password = ((String) o).toCharArray();85}8687/*88* Authenticate the user.89*/90@Override91public boolean login() throws LoginException {92// prompt for a user name and password93if (callbackHandler == null) {94throw new LoginException("No CallbackHandler available");95}9697// standard callbacks98NameCallback name = new NameCallback("username: ", "default");99PasswordCallback passwd = new PasswordCallback("password: ", false);100101LanguageCallback language = new LanguageCallback();102103TextOutputCallback error = new TextOutputCallback(104TextOutputCallback.ERROR, "This is an error");105TextOutputCallback warning = new TextOutputCallback(106TextOutputCallback.WARNING, "This is a warning");107TextOutputCallback info = new TextOutputCallback(108TextOutputCallback.INFORMATION, "This is a FYI");109110TextInputCallback text = new TextInputCallback("Please type " + HELLO,111"Bye");112113ChoiceCallback choice = new ChoiceCallback("Choice: ",114new String[] { "pass", "fail" }, 1, true);115116ConfirmationCallback confirmation = new ConfirmationCallback(117"confirmation: ", ConfirmationCallback.INFORMATION,118ConfirmationCallback.YES_NO_OPTION, ConfirmationCallback.NO);119120CustomCallback custom = new CustomCallback();121122Callback[] callbacks = new Callback[] {123choice, info, warning, error, name, passwd, text, language,124confirmation, custom125};126127boolean uce = false;128try {129callbackHandler.handle(callbacks);130} catch (UnsupportedCallbackException e) {131Callback callback = e.getCallback();132if (custom.equals(callback)) {133uce = true;134System.out.println("CustomLoginModule: "135+ "custom callback not supported as expected");136} else {137throw new LoginException("Unsupported callback: " + callback);138}139} catch (IOException ioe) {140throw new LoginException(ioe.toString());141}142143if (!uce) {144throw new RuntimeException("UnsupportedCallbackException "145+ "not thrown");146}147148if (!HELLO.equals(text.getText())) {149System.out.println("Text: " + text.getText());150throw new FailedLoginException("No hello");151}152153if (!Locale.GERMANY.equals(language.getLocale())) {154System.out.println("Selected locale: " + language.getLocale());155throw new FailedLoginException("Achtung bitte");156}157158String readUsername = name.getName();159char[] readPassword = passwd.getPassword();160if (readPassword == null) {161// treat a NULL password as an empty password162readPassword = new char[0];163}164passwd.clearPassword();165166// verify the username/password167if (!username.equals(readUsername)168|| !Arrays.equals(password, readPassword)) {169loginSucceeded = false;170throw new FailedLoginException("Username/password is not correct");171}172173// check chosen option174int[] selected = choice.getSelectedIndexes();175if (selected == null || selected.length == 0) {176throw new FailedLoginException("Nothing selected");177}178179if (selected[0] != 0) {180throw new FailedLoginException("Wrong choice: " + selected[0]);181}182183// check confirmation184if (confirmation.getSelectedIndex() != ConfirmationCallback.YES) {185throw new FailedLoginException("Not confirmed: "186+ confirmation.getSelectedIndex());187}188189loginSucceeded = true;190System.out.println("CustomLoginModule: authentication succeeded");191return true;192}193194/*195* This method is called if the LoginContext's overall authentication196* succeeded.197*/198@Override199public boolean commit() throws LoginException {200if (loginSucceeded) {201// add a Principal to the Subject202Principal principal = new TestPrincipal(username);203if (!subject.getPrincipals().contains(principal)) {204subject.getPrincipals().add(principal);205}206return true;207}208209return false;210}211212/*213* This method is called if the LoginContext's overall authentication214* failed.215*/216@Override217public boolean abort() throws LoginException {218loginSucceeded = false;219return true;220}221222/*223* Logout the user.224*/225@Override226public boolean logout() throws LoginException {227loginSucceeded = false;228boolean removed = subject.getPrincipals().remove(229new TestPrincipal(username));230if (!removed) {231throw new LoginException("Coundn't remove a principal: "232+ username);233}234return true;235}236237static class TestPrincipal implements Principal {238239private final String name;240241public TestPrincipal(String name) {242this.name = name;243}244245@Override246public String getName() {247return name;248}249250@Override251public String toString() {252return("TestPrincipal [name =" + name + "]");253}254255@Override256public int hashCode() {257return name.hashCode();258}259260@Override261public boolean equals(Object o) {262if (o == null) {263return false;264}265if (!(o instanceof TestPrincipal)) {266return false;267}268TestPrincipal other = (TestPrincipal) o;269return name != null ? name.equals(other.name) : other.name == null;270}271}272273static class CustomCallback implements Callback {}274}275276277