`
chun521521
  • 浏览: 283795 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

SAML2发送断言

 
阅读更多

 

已经认证的用户,直接向应用发送断言

 

package com.xxx;

 

import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.joda.time.DateTime;
import org.opensaml.Configuration;
import org.opensaml.saml2.core.*;
import org.opensaml.saml2.core.impl.AssertionBuilder;
import org.opensaml.saml2.core.impl.ResponseBuilder;
import org.opensaml.saml2.metadata.AssertionConsumerService;
import org.opensaml.saml2.metadata.Endpoint;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.security.CriteriaSet;
import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.credential.CredentialResolver;
import org.opensaml.xml.security.credential.UsageType;
import org.opensaml.xml.security.criteria.EntityIDCriteria;
import org.opensaml.xml.security.criteria.UsageCriteria;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

 

import com.xxx.saml.idp.BindingAdapter;
import com.xxx.saml.idp.IdpConfiguration;
import com.xxx.saml.idp.UIASAttributeStatementGenerator;
import com.xxx.saml.util.IDService;
import com.xxx.saml.util.TimeService;
import com.xxx.saml.xml.AttributeStatementGenerator;
import com.xxx.saml.xml.AuthnStatementGenerator;
import com.xxx.saml.xml.EndpointGenerator;
import com.xxx.saml.xml.IssuerGenerator;
import com.xxx.saml.xml.StatusGenerator;
import com.xxx.saml.xml.SubjectGenerator;
import com.xxx.uias.userInfo.pojo.Privilege;

 

public class TestServlet extends HttpServlet {
 private static final long serialVersionUID = 2572744487603163969L;

 private final XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
 private TimeService timeService = new TimeService();
 private IDService idService = new IDService();
 
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  this.doPost(req, resp);
 }

 @Override
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  try {
   request.setCharacterEncoding("utf-8");  //设置编码
   response.setContentType("text/html; charset=utf-8");
   
   String appCode = "demo333";
   String issuingEntityName = "UIAS";
   
   String acURL = "http://172.16.15.109:5050/aaa/samlsp/acService";
   int validForInSeconds = 300;
   String username = "testccc";
   String ip = "172.16.15.109";
   String inResponseTo = "";
   
   DateTime authnInstant = new DateTime(System.currentTimeMillis());
   
   AuthnStatementGenerator authnStatementGenerator = new AuthnStatementGenerator();
   AttributeStatementGenerator attributeStatementGenerator = new AttributeStatementGenerator();
   
   IssuerGenerator issuerGenerator = new IssuerGenerator(issuingEntityName);
   SubjectGenerator subjectGenerator = new SubjectGenerator(timeService);
   StatusGenerator statusGenerator = new StatusGenerator();
   
   
   //1.生成authResponse
   EndpointGenerator endpointGenerator = new EndpointGenerator();
   Endpoint endpoint = endpointGenerator.generateEndpoint(AssertionConsumerService.DEFAULT_ELEMENT_NAME, acURL, null);
   
   
   //2.
   ResponseBuilder responseBuilder = (ResponseBuilder) builderFactory.getBuilder(Response.DEFAULT_ELEMENT_NAME);
   Response authResponse = responseBuilder.buildObject();
   Issuer responseIssuer = issuerGenerator.generateIssuer();
   
   AssertionBuilder assertionBuilder = (AssertionBuilder)builderFactory.getBuilder(Assertion.DEFAULT_ELEMENT_NAME);
   Assertion assertion = assertionBuilder.buildObject();
   
   Subject subject = subjectGenerator.generateSubject(acURL, validForInSeconds, username, inResponseTo, ip);
   
   Issuer issuer = issuerGenerator.generateIssuer();
   
   AuthnStatement authnStatement = authnStatementGenerator.generateAuthnStatement(authnInstant);
   
   assertion.setIssuer(issuer);
   assertion.setSubject(subject);
   assertion.setID(idService.generateID());
   assertion.setIssueInstant(timeService.getCurrentDateTime());
   assertion.getAuthnStatements().add(authnStatement);
   
   //权限
         Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();;
         for(Privilege p: Privilege.values()){
          authorities.add(new SimpleGrantedAuthority("ROLE_" + p.name()));
   }
   assertion.getAttributeStatements().add(attributeStatementGenerator.generateAttributeStatement(authorities));
   
   //其他属性
   UIASAttributeStatementGenerator attrState = new UIASAttributeStatementGenerator();
   Map<String, String> attrMap = new HashMap<String, String>();
   attrMap.put("appCode", appCode);
   attrMap.put("name", "张三");
   assertion.getAttributeStatements().add(attrState.generateAttributeStatement(attrMap));
   
   
   authResponse.getAssertions().add(assertion);
   authResponse.setIssuer(responseIssuer);
   authResponse.setID(idService.generateID());
   authResponse.setIssueInstant(timeService.getCurrentDateTime());
   authResponse.setInResponseTo(inResponseTo);
   authResponse.setDestination(acURL);
   authResponse.setStatus(statusGenerator.generateStatus(StatusCode.SUCCESS_URI));
   
   //JKS
   CriteriaSet criteriaSet = new CriteriaSet();
   criteriaSet.add(new EntityIDCriteria(issuingEntityName));
   criteriaSet.add(new UsageCriteria(UsageType.SIGNING));
   CredentialResolver credentialResolver = IdpConfiguration.buildJKSCredentialResolver();
   Credential signingCredential = credentialResolver.resolveSingle(criteriaSet);
   
   
   BindingAdapter adapter = IdpConfiguration.buildBindingAdapter();
   adapter.sendSAMLMessage(authResponse, endpoint, signingCredential, response);
   
   
   
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 
 

}

 

 

 

 

 

该发送类为参考:

import java.io.PrintWriter;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import java.util.List;

import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.X509EncodedKeySpec;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.opensaml.common.binding.BasicSAMLMessageContext;
import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
import org.opensaml.ws.message.MessageContext;
import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.encryption.Decrypter;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.encryption.DecryptionException;
import org.opensaml.xml.encryption.InlineEncryptedKeyResolver;
import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver;
import org.opensaml.xml.security.x509.BasicX509Credential;
import org.opensaml.xml.signature.Signature;
import org.opensaml.xml.signature.SignatureValidator;
import org.opensaml.xml.validation.ValidationException;


public class ProcessSAML extends HttpServlet {
  
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        File signatureVerificationPublicKeyFile = new File("C:/IdPSigningCert.cer");
        File decryptionPrivateKeyFile = new File("C:/SPEncryptionCert.jks");
        String decryptionPrivateKeyName = "test";
        String decryptionPrivateKeyPassword = "test";

        try
        {
            //bootstrap the opensaml stuff
            org.opensaml.DefaultBootstrap.bootstrap();

            // get the message context
            MessageContext messageContext = new BasicSAMLMessageContext();
            messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request));
            HTTPPostDecoder samlMessageDecoder = new HTTPPostDecoder();
            samlMessageDecoder.decode(messageContext);

            // get the SAML Response
            Response samlResponse = (Response)messageContext.getInboundMessage();

            //get the certificate from the file
            InputStream inputStream2 = new FileInputStream(signatureVerificationPublicKeyFile);
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            X509Certificate certificate = (X509Certificate)certificateFactory.generateCertificate(inputStream2);
            inputStream2.close();

            //pull out the public key part of the certificate into a KeySpec
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(certificate.getPublicKey().getEncoded());

            //get KeyFactory object that creates key objects, specifying RSA
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");

            //generate public key to validate signatures
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

            //create credentials
            BasicX509Credential publicCredential = new BasicX509Credential();

            //add public key value
            publicCredential.setPublicKey(publicKey);

            //create SignatureValidator
            SignatureValidator signatureValidator = new SignatureValidator(publicCredential);

            //get the signature to validate from the response object
            Signature signature = samlResponse.getSignature();

            //try to validate
            try
            {
                signatureValidator.validate(signature);
            }
            catch (ValidationException ve)
            {
                out.println("Signature is not valid.");
                out.println(ve.getMessage());
                return;
            }

            //no validation exception was thrown
            out.println("Signature is valid.");

            //start decryption of assertion

            //load up a KeyStore
            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(new FileInputStream(decryptionPrivateKeyFile), decryptionPrivateKeyPassword.toCharArray());

            RSAPrivateKey privateKey = (RSAPrivateKey) keyStore.getKey(decryptionPrivateKeyName, decryptionPrivateKeyPassword.toCharArray());

            //create the credential
            BasicX509Credential decryptionCredential = new BasicX509Credential();
            decryptionCredential.setPrivateKey(privateKey);

            StaticKeyInfoCredentialResolver skicr = new StaticKeyInfoCredentialResolver(decryptionCredential);

            //create a decrypter
            Decrypter decrypter = new Decrypter(null, skicr, new InlineEncryptedKeyResolver());

            //decrypt the first (and only) assertion
            Assertion decryptedAssertion;

            try
            {
                decryptedAssertion = decrypter.decrypt(samlResponse.getEncryptedAssertions().get(0));
            }
            catch (DecryptionException de)
            {
                out.println("Assertion decryption failed.");
                out.println(de.getMessage());
                return;
            }

            out.println("Assertion decryption succeeded.");

            //loop through the nodes to get the Attributes
            //this is where you would do something with these elements
            //to tie this user with your environment
            List attributeStatements = decryptedAssertion.getAttributeStatements();
            for (int i = 0; i < attributeStatements.size(); i++)
            {
                List attributes = attributeStatements.get(i).getAttributes();
                for (int x = 0; x < attributes.size(); x++)
                {
                    String strAttributeName = attributes.get(x).getDOM().getAttribute("Name");

                    List attributeValues = attributes.get(x).getAttributeValues();
                    for (int y = 0; y < attributeValues.size(); y++)
                    {
                        String strAttributeValue = attributeValues.get(y).getDOM().getTextContent();
                        out.println(strAttributeName + ": " + strAttributeValue + " ");
                    }
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

    }

   
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

   
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

   
    @Override
    public String getServletInfo() {
        return "This servlet processes a SAML 2.0 Response.  It verifies the signature, " +
                "decrypts an assertion, and parses out the data in the attribute statements.  " +
                "If you use this code as a base for your implementation please leave the @author comment intact.  " +
                "You should add your own name in addition.";
    }

}

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    SAML v2 and XACML v2 Integration

    JBoss Identity项目集成了SAML v2和XACML v2的能力,这不仅体现了其在身份管理和访问控制方面的强大功能,还意味着它可以支持SAML v2规范中的XACML 2配置文件。这意味着,在JBoss平台上,可以通过SAML消息携带XACML...

    perl-Net-SAML2-master.zip-Net::SAML2 - SAML bindings and proto

    - **生成SAML断言**:IdP可以利用此模块创建并签署断言。 - **处理注销请求**:支持SAML注销流程的发起和响应处理。 5. **使用示例**: - 在Perl应用中,首先安装Net::SAML2模块(可能需要XML和加密库)。 - ...

    saml-client_java_saml_client_

    1. **身份验证请求(AuthnRequest)**: 用户尝试访问服务提供者(SP)的受保护资源,SP向身份提供者(IdP)发送一个SAML认证请求。 2. **身份验证响应(AuthnResponse)**: IdP验证用户身份后,返回一个包含认证结果...

    SAML 协议译本

    这个例子中,身份提供者(https://idp.example.org/SAML2)向服务提供者(https://sp.example.com/SAML2)发送了断言。 ```xml &lt;saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs=...

    SAML文档详细介绍.pdf

    2. **Relying Party(信任方)**:即服务提供商(Service Provider,SP),负责接收并验证由身份提供者发出的SAML断言,以此来决定是否允许主体访问其提供的服务。 3. **Asserting Party(断言方)**:也称身份...

    Learning SAML

    4. IdP验证用户成功后,生成一个包含用户身份信息的SAML断言,并将其发送回SP。 5. SP解析断言,确认用户已认证,然后允许用户访问资源。 三、SAML的类型 SAML主要有三种断言类型:身份认证断言、属性断言和授权...

    SAML2.0协议翻译.doc

    2. **服务提供商发起的SSO**(SP-initiated SSO):用户尝试访问SP服务时,如果未认证,SP会重定向用户到IdP进行身份验证,验证完成后返回SAML断言。 3. **响应/请求模式**(Response/Request Mode):SP可以主动向...

    saml第三方资料.rar

    2. **SAML 令牌提供程序**:SAML令牌提供程序是实现SSO系统的一部分,它生成SAML令牌,并将其发送给服务提供者(Service Provider, SP)。这些令牌包含了关于用户身份和权限的信息。 3. **什么是 SAML**:SAML是一...

    SAML2.0 简介

    #### 安全断言标记语言 (SAML 2.0) 安全断言标记语言(Security Assertion Markup Language, SAML)是一种用于交换认证与授权数据的标准协议,特别是适用于跨域单点登录(Single Sign-On, SSO)场景。SAML 2.0 是该...

    SAML2.0协议翻译

    2. **SAML绑定规范**(#SAMLBind):定义了如何使用不同的传输协议来发送SAML消息。 3. **SAML协议规范**(#SAMLProto):定义了身份提供者和服务提供者之间交互的消息格式和流程。 4. **SAML配置规范**(#...

    python-saml-master

    1. **源代码文件**:这些是实现SAML协议逻辑的Python代码,可能包括解析SAML响应、构建SAML请求、处理断言等。 2. **配置文件示例**:为了正确设置SAML环境,开发者需要配置一些参数,如元数据(Metadata)、私钥和...

    office 365 SAML2.0示例

    身份验证成功后,IdP 会生成一个包含用户信息的安全断言,并通过SAML响应发送给SP,SP依据这个断言来决定是否授权用户访问其资源。这一过程大大简化了用户的登录流程,同时也增强了系统的安全性。 在C#开发环境中,...

    saml2bearer-oauth-example

    您将需要将Okta SAML应用程序配置为将断言发送到服务器。 请遵循有关,但以下情况除外: 单一登录URL和受众URI应该是将接收SAML断言POST的应用程序的URL。 在此示例应用程序的情况下, https://localhost:8443/saml...

    sstc-saml-tech-overview-2.0

    4. **断言(Assertion)**:SAML中的基本数据单元,包含关于主体的声明信息,如身份验证状态、属性和授权决策。 SAML 2.0 还定义了一系列的消息格式和交互流程,以支持这些组件间的通信: - **认证请求...

    SAML翻译相关

    4. 如果用户成功认证,IdP创建一个SAML断言并将其发送回SP。 5. SP解析SAML断言,验证签名和时效性,然后基于断言中的信息做出授权决策,允许或拒绝用户访问。 在提供的文件列表中,“SAML”可能包含各种SAML相关的...

    SAML资料 V1.0 [OASIS 200205]

    2. **SAML协议(oasis-sstc-saml-schema-protocol-1.0.xsd)**: SAML协议定义了如何在IdP和SP之间交换SAML消息。包括请求和响应,例如身份验证请求、断言查询、断言消费等。协议也规定了不同绑定(Binding),如...

    WebLogic平台的Web SSO(SAML)解决方案

    2. **SAML断言**:SAML断言是SAML协议的核心,包含了关于用户身份、认证方法、认证时间等关键信息。断言由IDP创建,经加密或签名后发送给SP,确保了信息的安全性和完整性。 3. **IdentityAssertionProvider的角色**...

    django-saml2-sp:SAML 2.0服务提供商应用

    6. **中间件(Middleware)**:django-saml2-sp 可能包含特定的 Django 中间件,用于拦截请求,检查 SAML 断言并根据其结果进行相应的操作,如登录、登出或权限验证。 7. **设置与配置**:为了使用这个应用,开发者...

Global site tag (gtag.js) - Google Analytics