Sometimes when one application tries to call another application running on another server you get an error window with the message potential CSRF attack. At the same time you will see the following error message in the log files.
<BEA-000000> <A request has been denied as a potential CSRF attack.>
This issues arises due to the fact that WLS is not able to set the jsession id in the request made to the other server.
To address this issue we need to add the following in weblogic.xml
It is useful to send custom attributes or tokens in the attribute having identity information of the authenticated user.This identity information can be further used by the detination site to access services on behalf of the user. To implement a SAML Attribute Mapper on Weblogic Server, you need to follow the steps below.
1 . Create SAMLAttributeMapperInfoExample class that implements SAMLCredentialAttributeMapper
package samlWrapper;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import javax.security.auth.Subject;
import weblogic.security.providers.saml.SAMLAttributeStatementInfo;
import weblogic.security.providers.saml.SAMLAttributeInfo;
import weblogic.security.providers.saml.SAMLCredentialNameMapper;
import weblogic.security.providers.saml.SAMLCredentialAttributeMapper;
import weblogic.security.providers.saml.SAMLNameMapperInfo;
import weblogic.security.service.ContextHandler;
import weblogic.security.service.ContextElement;
import weblogic.security.spi.WLSGroup;
import weblogic.security.spi.WLSUser;
public class SAMLAttributeMapperInfoExample implements
SAMLCredentialNameMapper,SAMLCredentialAttributeMapper
{
private final static String defaultAuthMethod =
"urn:oasis:names:tc:SAML:1.0:am:unspecified";
private final static String SAML_CONTEXT_ATTRIBUTE_NAME =
"com.bea.contextelement.saml.context.attribute.name";
private String nameQualifier = null;
private String authMethod = defaultAuthMethod;
public SAMLAttributeMapperInfoExample()
{
// make constructor public
}
/**
* Set the name qualifier value
*/
public synchronized void setNameQualifier(String nameQualifier) {
this.nameQualifier = nameQualifier;
}
/**
* Map a <code>Subject</code> and return mapped user and group
* info as a <code>SAMLNameMapperInfo</code> object.
*/
public SAMLNameMapperInfo mapSubject(Subject subject, ContextHandler handler) {
// Provider checks for null Subject...
Set subjects = subject.getPrincipals(WLSUser.class);
Set groups = subject.getPrincipals(WLSGroup.class);
String userName = null;
if (subjects == null || subjects.size() == 0) {
System.out.println("No valid subject found ");
return null;
}
if (groups == null || groups.size() == 0) {
System.out.println("mapSubject: No valid WLSGroup pricipals found in Subject, continuing");
}
if (subjects.size() != 1) {
System.out.println("mapSubject: More than one WLSUser principal found in Subject, taking first user only");
}
userName = ((WLSUser)subjects.iterator().next()).getName();
if (userName == null || userName.equals("")) {
System.out.println("mapSubject: Username string is null or empty, returning null");
return null;
}
// Return mapping information...
System.out.println("mapSubject: Mapped subject: qualifier: " +nameQualifier + ", name: " + userName + ", groups: " + groups);
return new SAMLNameMapperInfo(nameQualifier, userName,groups);
}
/**
* Map a <code>String</code> subject name and return mapped user and group
* info as a <code>SAMLNameMapperInfo</code> object.
*/
public SAMLNameMapperInfo mapName(String name, ContextHandler handler) {
System.out.println("mapName: Mapped name: qualifier: " +nameQualifier + ", name: " + name);
return new SAMLNameMapperInfo(nameQualifier, name, null);
}
/**
* Returns the SAML AttributeName for group information.
*
* @return The AttributeName.
*/
public String getGroupAttrName() {
return SAMLNameMapperInfo.BEA_GROUP_ATTR_NAME;
}
/**
* Returns the SAML AttributeNamespace for group information.
*
* @return The AttributeNamespace.
*/
public String getGroupAttrNamespace() {
return SAMLNameMapperInfo.BEA_GROUP_ATTR_NAMESPACE;
}
/**
* set the method.
* @param method String
*/
public void setAuthenticationMethod(String method)
{
if (method != null)
authMethod = method;
}
/**
* get the auth method
* @return method String
*/
public String getAuthenticationMethod()
{
return authMethod;
}
/**
* maps a Subject/Context to a Collection of SAMLAttributeStatementInfo
* instances.
*
* @return <code>Collection</code>
*/
public Collection mapAttributes(Subject subject, ContextHandler handler)
{
ArrayList statementList=null;
try{
System.out.println("mapAttributes: Subject: "+subject.toString()+",ContextHandler: "+handler.toString());
String[] names = handler.getNames();
for ( String name : names){
System.out.println("name=="+name);
}
Object element = handler.getValue(SAML_CONTEXT_ATTRIBUTE_NAME);
System.out.println("mapAttributes: got element from ContextHandler");
System.out.println("mapAttributes: element is a:"+element);
/* */
TestAttribute[] tas = new TestAttribute[1];
TestAttribute t1 = new TestAttribute();
tas[0]= t1;
// tas = (TestAttribute[])element;
System.out.println("attributes set!");
/*
* loop through all test attributes and write a SAMLAttributeStatementInfo
* for each one.
*/
statementList = new ArrayList();
for (int k = 0; k < tas.length; k++)
{
ArrayList al = null;
String[] values = tas[k].getValues();
if (values != null)
{
al = new ArrayList();
for (int i = 0; i < values.length; i++)
if (values[i] != null)
al.add(values[i]);
else al.add("");
}
System.out.println("values added!");
SAMLAttributeInfo ai = new SAMLAttributeInfo(tas[k].getName(),
tas[k].getNamespace(), al);
SAMLAttributeStatementInfo asi = new
SAMLAttributeStatementInfo();
asi.addAttributeInfo(ai);
statementList.add(asi);
System.out.println("added to list");
}
}catch(Exception e){
e.printStackTrace();
}
System.out.println("returning");
return statementList;
}
}
2. Create your test attribute
package samlWrapper;
public class TestAttribute {
public String getNamespace(){
return "research.iiit.ac.in";
}
public String getName(){
return "KEY";
}
public String[] getValues() {
String[] strArr = new String[1];
GetKeyInfo info = new GetKeyInfo();
try{
strArr[0] =info.getKeyInfo() ;
}catch(Exception e){
e.printStackTrace();
}
return strArr;
}
}
3. Compile the code and create a jar file.
javac -d . *. java
jar -cvf samlAttributeWrapper.jar samlWrapper
4. Add the jar in the classpath of Weblogic Server
5. Restart Weblogic Server
6. Go to
Home >Summary of Security Realms >myrealm >Providers >SAMLCredentialMapperV2
7. Restart Weblogic Server.
You will be able to see the attribute in the SAML Assertion
We can start WebLogic server with the following JVM option
-Dweblogic.security.SSL.protocolVersion=TLS1
Ref :-
http://weblogic-wonders.com/weblogic/2009/12/08/use-specific-ssl-protocol-version-with-weblogic-server/ Disable support for CBC-based cipher suites when using SSL 3.0 (in either client or server).
This article provides sample Webservice and Webservice Client for two way SSL. It also demonstrates the use of WLSSSLAdapter class to send certificates to the server.
1. Create a JWS with the following policy : Wssp1.2-2007-Https-ClientCertReq.xml
2. Build and Deploy the service on WebLogic Server
3. Deploy a war file with the following jsp in another server.
<html>
<head>
<title>WS Client App</title>
</head>
<body bgcolor="#cccccc">
<blockquote>
<h2>Protected Page</h2>
</blockquote>
<%@ page import="examples.webservices.security_jws.client.SecureHelloWorldService"%>
<%@ page import="examples.webservices.security_jws.client.SecureHelloWorldService_Impl"%>
<%@ page import="examples.webservices.security_jws.client.SecureHelloWorldPortType"%>
<%@ page import="javax.xml.rpc.Stub"%>
<%@ page import="weblogic.wsee.connection.transport.https.WlsSSLAdapter"%>
<%@ page import="weblogic.security.SSL.TrustManager"%>
<%@ page import="java.security.cert.X509Certificate"%>
<%
try
{
String wsdl = "https://localhost:7002/SecureHelloWorldService/SecureHelloWorldService?WSDL";
//SecureHelloWorldService service = new SecureHelloWorldService_Impl(wsdl);
SecureHelloWorldService service = new SecureHelloWorldService_Impl();
SecureHelloWorldPortType port = service.getSecureHelloWorldServicePort();
WlsSSLAdapter adapter = new WlsSSLAdapter();
adapter.setKeystore("C://WSSecurity//LABS//twoway_jws//identity.jks","mystorepass".toCharArray(), "JKS" );
adapter.setClientCert("mykey","mykeypass".toCharArray());
adapter.setTrustManager( new TrustManager(){
public boolean certificateCallback(X509Certificate[] chain, int validateErr){
return true;
}
});
weblogic.wsee.connection.transport.https.HttpsTransportInfo info = new weblogic.wsee.connection.transport.https.HttpsTransportInfo(adapter);
Stub stub = (Stub)port;
stub._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY,"https://localhost:7002/SecureHelloWorldService/SecureHelloWorldService?WSDL");
stub._setProperty("weblogic.wsee.client.ssladapter", adapter);
out.println(port.sayHello("World"));
}
catch (Exception e)
{
out.println("File input error"+e);
}
%>
</body>
</html>
4. Configure SSL on the server on which client app is deployed.
5. On the server on which the service is deployed , do the 2 way SSL configuration.
a) Go to Home >Summary of Servers > YourServer > SSL > Advanced > Two Way Client Cert Behavior: Client Certs Requested and Enforced Hostname Verification: None
b) Go to Home >Summary of Security Realms >myrealm >Providers >DefaultIdentityAsserter
Under Common
Chosen Select X509
Under Provider Specific
Trusted Client Principals: <CN of the client’s certificate> Default User Name Mapper Attribute Type: CN Use Default User Name Mapper: Checked
c) Create a user in the security realm with the CN value of the certificate.
6) Import the client’s public certificate in the trust store of the server.