如何从 Jboss EAP 中的 HTTPServerAuthModule 中删除身份验证

How to remove authentication from HTTPServerAuthModule in Jboss EAP

我需要创建一个类似于 HTTPBasicServerAuthModule 的自定义身份验证模块,它不应提示输入用户名和密码进行身份验证。因为,我们有一个 jwt 令牌会为我们处理身份验证,我们不需要另一层身份验证。以下是我的自定义身份验证模块:

public class CustomJaspiAuthModule extends WebServerAuthModule
{
    protected Context context;
    protected boolean cache = false;
    public static final byte[] AUTHENTICATE_BYTES = {
        (byte) 'W',
        (byte) 'W',
        (byte) 'W',
        (byte) '-',
        (byte) 'A',
        (byte) 'u',
        (byte) 't',
        (byte) 'h',
        (byte) 'e',
        (byte) 'n',
        (byte) 't',
        (byte) 'i',
        (byte) 'c',
        (byte) 'a',
        (byte) 't',
        (byte) 'e'
    };
    protected String delegatingLoginContextName = null;

    public CustomJaspiAuthModule() { }

    public CustomJaspiAuthModule(String delegatingLoginContextName) {
        super();
        this.delegatingLoginContextName = delegatingLoginContextName;
    }

    @Override
    public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException {
        // do nothing, just return SUCCESS.
        return AuthStatus.SUCCESS;
    }

    @Override
    public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException {
        Request request = (Request) messageInfo.getRequestMessage();
        Response response = (Response) messageInfo.getResponseMessage();

        Principal principal;
        context = request.getContext();
        LoginConfig config = context.getLoginConfig();

        // validate any credentials already included with this request.
        String username = null;
        String password = null;

        MessageBytes authorization = request.getCoyoteRequest().getMimeHeaders().getValue("authorization");

        if (authorization != null) {
            authorization.toBytes();
            ByteChunk authorizationBC = authorization.getByteChunk();

            if (authorizationBC.startsWithIgnoreCase("basic ", 0)) {
                authorizationBC.setOffset(authorizationBC.getOffset() + 6);
                CharChunk authorizationCC = authorization.getCharChunk();
                Base64.decode(authorizationBC, authorizationCC);

                // get username and password from the authorization char chunk.
                int colon = authorizationCC.indexOf(':');
                if (colon < 0) {
                    username = authorizationCC.toString();
                } else {
                    char[] buf = authorizationCC.getBuffer();
                    username = new String(buf, 0, colon);
                    password = new String(buf, colon + 1, authorizationCC.getEnd() - colon - 1);
                }

                authorizationBC.setOffset(authorizationBC.getOffset() - 6);
            }

            principal = context.getRealm().authenticate(username, password);
            if (principal != null) {
                registerWithCallbackHandler(principal, username, password);

                return AuthStatus.SUCCESS;
            }
        }

        // send an "unauthorized" response and an appropriate challenge.
        MessageBytes authenticate = response.getCoyoteResponse().getMimeHeaders().
                addValue(AUTHENTICATE_BYTES, 0, AUTHENTICATE_BYTES.length);

        CharChunk authenticateCC = authenticate.getCharChunk();
        try {
            authenticateCC.append("Basic realm=\"");
            if (config.getRealmName() == null) {
                authenticateCC.append(request.getServerName());
                authenticateCC.append(':');
                authenticateCC.append(Integer.toString(request.getServerPort()));
            } else {
                authenticateCC.append(config.getRealmName());
            }
            authenticateCC.append('\"');
            authenticate.toChars();

            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        } catch (IOException e) {
            // Ignore IOException here (client disconnect)
        }

        return AuthStatus.FAILURE;
    }

}

我相信代码的以下部分是我们提示输入用户名和密码警报以进行身份​​验证的原因。

MessageBytes authenticate = response.getCoyoteResponse().getMimeHeaders().
                addValue(AUTHENTICATE_BYTES, 0, AUTHENTICATE_BYTES.length);

        CharChunk authenticateCC = authenticate.getCharChunk();
        try {
            authenticateCC.append("Basic realm=\"");
            if (config.getRealmName() == null) {
                authenticateCC.append(request.getServerName());
                authenticateCC.append(':');
                authenticateCC.append(Integer.toString(request.getServerPort()));
            } else {
                authenticateCC.append(config.getRealmName());
            }
            authenticateCC.append('\"');
            authenticate.toChars();

            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        } catch (IOException e) {
            // Ignore IOException here (client disconnect)
        }

但是如果我删除这个块,我会得到一个很好的响应(200 响应)但是我得到的请求和响应是空的。请建议我如何删除此身份验证警报。

我写了一个如下所示的自定义身份验证模块,它达到了我的目的:

public class CustomJaspiAuthModule extends WebServerAuthModule 
{
    private static final String CLASSNAME   = "CustomJaspiAuthModule";
    private static Logger       logger      = Logger.getLogger(CustomJaspiAuthModule.class.getName());

    protected Context context;
    protected String delegatingLoginContextName = null;

    public CustomJaspiAuthModule() { }

    public CustomJaspiAuthModule(String delegatingLoginContextName) 
    {
        super();
        this.delegatingLoginContextName = delegatingLoginContextName;
    }

    @Override
    public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException 
    {
        // do nothing, just return SUCCESS.
        return AuthStatus.SUCCESS;
    }

    @Override
    public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException 
    {
        final String METHOD_NAME = "validateRequest";
        logger.logp(Level.INFO, CLASSNAME, METHOD_NAME, "**IN AUTHENTICATION MODULE**CustomJaspiAuthModule.validateRequest()");

        Request request = (Request) messageInfo.getRequestMessage();
        Response response = (Response) messageInfo.getResponseMessage();

        boolean authenticated = false;
        context = request.getContext();
        Principal principal = context.getRealm().authenticate("*", "*");

        Callback[] callbacks = new Callback[] {
                new CallerPrincipalCallback(clientSubject, (Principal) null) };

        if (principal != null) 
        {
            callbacks = new Callback[] { 
                    new CallerPrincipalCallback(clientSubject, principal) };
            authenticated = true;
        } 

        if (authenticated) 
        {
            try 
            {
                callbackHandler.handle(callbacks);
            } 
            catch (final Exception e) 
            {
                throw (AuthException) new AuthException().initCause(e);
            }
            return AuthStatus.SUCCESS;
        }

        return AuthStatus.FAILURE;
    }
}