/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.wss4j.stax.validate; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import org.apache.commons.codec.binary.Base64; import org.apache.wss4j.binding.wss10.EncodedString; import org.apache.wss4j.binding.wss10.PasswordString; import org.apache.wss4j.binding.wss10.UsernameTokenType; import org.apache.wss4j.binding.wsu10.AttributedDateTime; import org.apache.wss4j.common.NamePasswordCallbackHandler; import org.apache.wss4j.common.ext.WSSecurityException; import org.apache.wss4j.stax.ext.WSSConstants; import org.apache.wss4j.stax.securityToken.UsernameSecurityToken; import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants; import org.apache.wss4j.stax.impl.securityToken.UsernameSecurityTokenImpl; import org.apache.xml.security.stax.ext.XMLSecurityUtils; import org.apache.xml.security.stax.securityToken.InboundSecurityToken; /** * This class validates a processed UsernameToken, where Username/password validation is delegated * to the JAAS LoginContext. */ public class JAASUsernameTokenValidatorImpl implements UsernameTokenValidator { private static final transient org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(JAASUsernameTokenValidatorImpl.class); private String contextName; public void setContextName(String name) { contextName = name; } public String getContextName() { return contextName; } @Override public <T extends UsernameSecurityToken & InboundSecurityToken> T validate( UsernameTokenType usernameTokenType, TokenContext tokenContext) throws WSSecurityException { PasswordString passwordType = XMLSecurityUtils.getQNameType(usernameTokenType.getAny(), WSSConstants.TAG_WSSE_PASSWORD); WSSConstants.UsernameTokenPasswordType usernameTokenPasswordType = WSSConstants.UsernameTokenPasswordType.PASSWORD_NONE; if (passwordType != null && passwordType.getType() != null) { usernameTokenPasswordType = WSSConstants.UsernameTokenPasswordType.getUsernameTokenPasswordType(passwordType.getType()); } // Digest not supported if (usernameTokenPasswordType != WSSConstants.UsernameTokenPasswordType.PASSWORD_TEXT) { LOG.warn("Password type is not supported"); throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION); } String username = null; if (usernameTokenType.getUsername() != null) { username = usernameTokenType.getUsername().getValue(); } String password = null; if (passwordType != null) { password = passwordType.getValue(); } if (username == null || username.isEmpty() || password == null || password.isEmpty()) { LOG.warn("User or password empty"); throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION); } Subject subject; try { CallbackHandler handler = getCallbackHandler(username, password); LoginContext ctx = new LoginContext(getContextName(), handler); ctx.login(); subject = ctx.getSubject(); } catch (LoginException ex) { LOG.info("Authentication failed", ex); throw new WSSecurityException( WSSecurityException.ErrorCode.FAILED_AUTHENTICATION, ex ); } final EncodedString encodedNonce = XMLSecurityUtils.getQNameType(usernameTokenType.getAny(), WSSConstants.TAG_WSSE_NONCE); byte[] nonceVal = null; if (encodedNonce != null) { if (!WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING.equals(encodedNonce.getEncodingType())) { throw new WSSecurityException(WSSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN, "badTokenType01"); } nonceVal = Base64.decodeBase64(encodedNonce.getValue()); } final AttributedDateTime attributedDateTimeCreated = XMLSecurityUtils.getQNameType(usernameTokenType.getAny(), WSSConstants.TAG_WSU_CREATED); UsernameSecurityTokenImpl usernameSecurityToken = new UsernameSecurityTokenImpl( usernameTokenPasswordType, username, password, attributedDateTimeCreated != null ? attributedDateTimeCreated.getValue() : null, nonceVal, null, null, tokenContext.getWsSecurityContext(), usernameTokenType.getId(), WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE); usernameSecurityToken.setElementPath(tokenContext.getElementPath()); usernameSecurityToken.setXMLSecEvent(tokenContext.getFirstXMLSecEvent()); usernameSecurityToken.setSubject(subject); @SuppressWarnings("unchecked") T token = (T)usernameSecurityToken; return token; } protected CallbackHandler getCallbackHandler(String name, String password) { return new NamePasswordCallbackHandler(name, password); } }