Wildfly-FailedLoginException:密码错误/需要密码例外

问题描述 投票:2回答:1

我有一个用JAVA编写并部署在Wildfly 8.2上的小型REST应用程序。我收到错误FailedLoginException:密码错误/密码尝试使用javax安全性库登录时需要此密码。这可能是什么原因?

我从浏览器发送的请求是URL http://localhost:8080/ACWildfly/loginService/login

这里是LoginService类:

package com.om.targin.admin;

import org.jboss.security.auth.callback.UsernamePasswordHandler;

import javax.security.auth.login.LoginContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

@Path("/loginService")
public class LoginService {

    //  private static final Log logger = LogFactory.getFactory().getLog(LoginService.class.getName());

    @GET
    @Path("/login")
    public Response login() {
        //   logger.info("LoginService login is called.");
        try {
            LoginContext lc = null;
            String username = "UseR_U";
            String password = "hashedpassword";
            UsernamePasswordHandler handler = new UsernamePasswordHandler(username,
                    password == null ? null : password.toCharArray());
            lc = new LoginContext("targin-client", handler);
            lc.login();
            return Response.status(Response.Status.OK).build();
        }
        catch (Exception e){
            // logger.error("Exception has been occurred."+e.getMessage());
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
        }
    }
}

RestApplication类:

package com.om.targin.admin;

import org.glassfish.jersey.server.ResourceConfig;

import javax.ws.rs.ApplicationPath;

@ApplicationPath("/")
public class RestApplication extends ResourceConfig {

    public RestApplication() {
        packages("com.om.targin.admin");
    }
}

登录模块:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.jboss.login">
    <resources>
    <resource-root path="SPLoginModule.jar"/>
    </resources>

    <dependencies>
       <module name="org.picketbox"/>
       <module name="javax.api"/>
    </dependencies>
</module>

SPLoginModule类:

package tr.com.splogin;

import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.spi.AbstractServerLoginModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.sql.DataSource;
import java.security.Principal;
import java.security.acl.Group;
import java.sql.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class SPLoginModule extends AbstractServerLoginModule {
    private static final int USER_LOCKEDOUT = 23;
    private static final int USER_VALFAIL = 24;
    private static final int USER_MAXATTEMPTS = 25;

    private static final String ROLE_GROUP_NAME = "Roles";
    private static final String ID_GROUP_NAME = "Id";

    private static Logger logger = LoggerFactory.getLogger(SPLoginModule.class);

    private static final SimplePrincipal GUEST = new SimplePrincipal("guest");
    private static boolean initialized = false;
    private static boolean initFailed = false;
    private static Connection conn;
    private static CallableStatement cs;
    private static PreparedStatement ps;
    private static ResultSet rs;
    /**
     * The principal to use when a null username and password are seen
     */
    private static Principal unauthenticatedIdentity;
    private static Map options;

    /**
     * The roles of the authenticated user
     */
    private Group[] roleSets;
    /**
     * The proof of login identity
     */
    private char[] credential;
    /**
     * The login identity
     */
    private Principal identity;

    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
        logger.info("initialize start");
        System.out.println("initialize start");
        super.initialize(subject, callbackHandler, sharedState, options);
        if (!initialized) {
            this.options = options;
            init(options);
            initialized = true;
        }
        logger.info("initialize stop");
    }

    private String getUsername() {
        String username = null;
        if (getIdentity() != null)
            username = getIdentity().getName();
        return username;
    }

    public boolean login() throws LoginException {
        System.out.println("login is called.");
        String[] info = getUsernameAndPassword();
        String username = info[0];
        String password = info[1];

        logger.info(username);
        logger.info(password);

        super.loginOk = false;

        if (username == null && password == null) {
            identity = unauthenticatedIdentity;
            Group roles = new SimpleGroup(ROLE_GROUP_NAME);
            Set groups = new HashSet();
            groups.add(roles);
            roles.addMember(GUEST);
            roleSets = new Group[groups.size()];
            groups.toArray(roleSets);
            logger.info("Authenticating as unauthenticatedIdentity=" + identity);
        }

        if (identity == null) {
            identity = new SimplePrincipal(username);
            login(username, password);
        }

        super.loginOk = true;
        logger.info("User '" + identity + "' authenticated, loginOk=" + loginOk);
        return true;
    }

    public Principal getIdentity() {
        return identity;
    }

    public Group[] getRoleSets() {
        return roleSets;
    }

    private void login(String username, String password) throws LoginException {
        System.out.println("login is called.");
        try {
            int userIdCode = 3;
            int resultCode = 4;
            int result, userId;

            cs.setString(1, username);
            cs.setString(2, password);
            cs.registerOutParameter(userIdCode, Types.INTEGER);
            cs.registerOutParameter(resultCode, Types.INTEGER);

            cs.execute();

            result = cs.getInt(resultCode);

            if (result == 0) {
                userId = cs.getInt(userIdCode);
                logger.info("Id: " + userId);

                Group roles = new SimpleGroup(ROLE_GROUP_NAME);
                Group id = new SimpleGroup(ID_GROUP_NAME);
                Set groups = new HashSet();
                String roleName;

                groups.add(roles);
                groups.add(id);

                ps.setInt(1, userId);
                rs = ps.executeQuery();

                id.addMember(new SimplePrincipal((new Integer(userId)).toString()));

                while (rs.next()) {
                    roleName = rs.getString(1);
                    logger.debug("Action: " + roleName);
                    roles.addMember(new SimplePrincipal(roleName));
                }
                roles.addMember(GUEST);

                roleSets = new Group[groups.size()];
                groups.toArray(roleSets);
            } else {
                String message = new String();
                roleSets = new Group[0];

                switch (result) {
                    case USER_VALFAIL:
                        System.out.println("login is failed.");
                        message = new String("Login failed");
                        break;
                    case USER_LOCKEDOUT:
                        message = new String("User is locked out");
                        break;
                    case USER_MAXATTEMPTS:
                        message = new String("Max number of attempts reached, user is locked out");
                        break;
                    default:
                        message = new String("Unkown failed login error with code: " + result);
                        break;
                }
                logger.info("Error result code: " + result);
                logger.info("Error message: " + message);
                throw new FailedLoginException(message);
            }
        } catch (SQLException e) {
            logger.error(e.toString());
            init(options);
            if (!initFailed)
                login(username, password);
        } finally {
            try {
                if (rs != null)
                    rs.close();
            } catch (SQLException e1) {
                logger.error(e1.toString());
            }
        }
    }

    private void init(Map options) {
        logger.info("init");
        try {
            if (cs != null)
                cs.close();
            if (ps != null)
                ps.close();
            if (conn != null)
                conn.close();
        } catch (SQLException e) {
            logger.error(e.toString());
        }

        try {
            InitialContext ctx = new InitialContext();
            DataSource ds = (DataSource) ctx.lookup("java:/OracleDS");

            conn = ds.getConnection();
            String sp_login = "{call admin_pck.pc_login(?,?,?,?)}";
            String query_user_action = "select aa.name from admin_user au,admin_role ar,admin_action aa,admin_user_role aur,admin_role_action ara,owner o where au.id=? and aur.id_admin_user=au.id and aa.id=ara.id_admin_action and ara.id_admin_role=ar.id and ar.id=aur.id_role and o.id=aur.id_owner and o.id=au.id_primary_owner order by aa.name";

            cs = conn.prepareCall(sp_login);
            ps = conn.prepareStatement(query_user_action);

            String name = (String) options.get("unauthenticatedIdentity");
            if (name != null) {
                unauthenticatedIdentity = new SimplePrincipal(name);
                logger.info("Saw unauthenticatedIdentity=" + name);
            }
            initFailed = false;
        } catch (NamingException e) {
            logger.error(e.toString());
            initFailed = true;
        } catch (SQLException e) {
            logger.error(e.toString());
            initFailed = true;
        }
    }

    /**
     * Called by login() to acquire the username and password strings for
     * authentication. This method does no validation of either.
     *
     * @return String[], [0] = username, [1] = password
     * @throws LoginException thrown if CallbackHandler is not set or fails.
     */
    protected String[] getUsernameAndPassword() throws LoginException {
        String[] info = {null, null};
        // prompt for a username and password
        if (callbackHandler == null) {
            throw new LoginException("Error: no CallbackHandler available to collect authentication information");
        }
        NameCallback nc = new NameCallback("User name: ");
        PasswordCallback pc = new PasswordCallback("Password: ", false);
        Callback[] callbacks = {nc, pc};
        String username = null;
        String password = null;
        try {
            callbackHandler.handle(callbacks);
            username = nc.getName();
            char[] tmpPassword = pc.getPassword();
            if (tmpPassword != null) {
                credential = new char[tmpPassword.length];
                System.arraycopy(tmpPassword, 0, credential, 0, tmpPassword.length);
                pc.clearPassword();
                password = new String(credential);
            }
        } catch (java.io.IOException e) {
            throw new LoginException(e.toString());
        } catch (UnsupportedCallbackException e) {
            throw new LoginException("CallbackHandler does not support: " + e.getCallback());
        }
        info[0] = username;
        info[1] = password;
        return info;
    }
}

WEB-INF下的jboss-deploynment-structure.xml:

<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="org.jboss.login" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>

WEB-INF下的jboss-web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web version="7.1" xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/schema/jbossas/jboss-web_7_1.xsd">
    <security-domain>java:/jaas/targin-server</security-domain>
</jboss-web>

standalone-full.xml安全域配置:

<security-domain name="targin-server" cache-type="default">
                    <authentication>
                        <login-module code="tr.com.splogin.SPLoginModule" flag="required" module="org.jboss.login">
                            <module-option name="unauthenticatedIdentity" value="guest"/>
                        </login-module>
                    </authentication>
                </security-domain>

Oracle数据源:

<datasource jta="true" jndi-name="java:/OracleDS" pool-name="OracleDS" enabled="true" use-ccm="true">
                    <connection-url>jdbc:oracle:thin:@10.23.4.567:1521:DBSID</connection-url>
                    <driver-class>oracle.jdbc.OracleDriver</driver-class>
                    <driver>oracle</driver>
                    <security>
                        <user-name>dbuser</user-name>
                        <password>dbpass</password>
                    </security>
                    <validation>
                        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
                        <background-validation>true</background-validation>
                        <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
                        <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
                    </validation>
                </datasource>

Stacktrace:

Exception e: javax.security.auth.login.FailedLoginException: PBOX000070: Password invalid/Password required

org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:284)"
org.jboss.as.security.RealmDirectLoginModule.login(RealmDirectLoginModule.java:147)"
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)"
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)"
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)"
java.lang.reflect.Method.invoke(Unknown Source)"
javax.security.auth.login.LoginContext.invoke(Unknown Source)"
javax.security.auth.login.LoginContext.access$000(Unknown Source)"
javax.security.auth.login.LoginContext$4.run(Unknown Source)"
javax.security.auth.login.LoginContext$4.run(Unknown Source)"
"java.security.AccessController.doPrivileged(Native Method)"
javax.security.auth.login.LoginContext.invokePriv(Unknown Source)"
javax.security.auth.login.LoginContext.login(Unknown Source)"
com.om.targin.admin.LoginService.login(LoginService.java:26)"
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)"
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)"
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)"
java.lang.reflect.Method.invoke(Unknown Source)"
org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137)"
org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296)"
org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250)"
org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:237)"
org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356)"
org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179)"
org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)"
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)"
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)"
javax.servlet.http.HttpServlet.service(HttpServlet.java:790)"
io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86)"
io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)"
io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)"
org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)"
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"
io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)"
io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)"
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"
io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)"
io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)"
io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)"
io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)"
io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)"
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"
org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)"
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"
io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261)"
io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:248)"
io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:77)"
io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:167)"
io.undertow.server.Connectors.executeRootHandler(Connectors.java:199)"
io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:761)"
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)"
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)"
java.lang.Thread.run(Unknown Source)

提前感谢。

java oracle rest authentication wildfly-8
1个回答
0
投票

我知道了。实际上,这是一个很小而愚蠢的错误。

在我的LoginService类中,当它创建Logincontext时,我将名称参数作为'targin-client'传递,而我应将其作为'targin-server'传递,这是我为该应用定义的登录模块。

        LoginContext lc = null;
        String username = "UseR_U";
        String password = "hashedpassword";
        UsernamePasswordHandler handler = new UsernamePasswordHandler(username,
                password == null ? null : password.toCharArray());
        lc = new LoginContext("targin-client", handler);
        lc.login();

正确的版本是:

        lc = new LoginContext("targin-server", handler);

在创建登录上下文时,我们传入一个安全域,该安全域指向在Wildfly模块下定义并处理身份验证的登录模块。另外,请注意,我正在使用Wildfly的Picketbox安全性库。 SPLoginModule类从此库继承。

干杯。

© www.soinside.com 2019 - 2024. All rights reserved.