Is there a way to create SAML assertions in Node.js - wso2

I am using a Java client to generate custom SAML assertions to get OAuth tokens from WSO2 API Manager which supports SAML2 Bearer Assertion Profile. (https://nallaa.wordpress.com/2013/04/04/saml2-bearer-assertion-profile-for-oauth-2-0-with-wso2-identity-server/)
This is to issue OAuth tokens to anonymous users who dont have a login in WSO2 IS. I am generating small id for these users. Using that unique id I generate SAML assertions.
Now I want to move this logic to node.js. Is there a way to create SAML assertions in node.js similar to this logic?
private Assertion buildSAMLAssertion() throws Exception {
DefaultBootstrap.bootstrap();
Assertion samlAssertion = new AssertionBuilder().buildObject();
try {
DateTime currentTime = new DateTime();
DateTime notOnOrAfter = new DateTime(currentTime.getMillis() + 60 * 60 * 1000);
samlAssertion.setID(createID());
samlAssertion.setVersion(SAMLVersion.VERSION_20);
samlAssertion.setIssuer(getIssuer());
samlAssertion.setIssueInstant(currentTime);
Subject subject = new SubjectBuilder().buildObject();
NameID nameId = new NameIDBuilder().buildObject();
nameId.setValue(username);
nameId.setFormat(NameIdentifier.EMAIL);
subject.setNameID(nameId);
SubjectConfirmation subjectConfirmation =
new SubjectConfirmationBuilder().buildObject();
subjectConfirmation.setMethod("urn:oasis:names:tc:SAML:2.0:cm:bearer");
SubjectConfirmationData scData = new SubjectConfirmationDataBuilder().buildObject();
scData.setRecipient(recipient);
scData.setNotOnOrAfter(notOnOrAfter);
scData.setInResponseTo(id);
subjectConfirmation.setSubjectConfirmationData(scData);
subject.getSubjectConfirmations().add(subjectConfirmation);
samlAssertion.setSubject(subject);
AuthnStatement authStmt = new AuthnStatementBuilder().buildObject();
authStmt.setAuthnInstant(new DateTime());
AuthnContext authContext = new AuthnContextBuilder().buildObject();
AuthnContextClassRef authCtxClassRef = new AuthnContextClassRefBuilder().buildObject();
authCtxClassRef.setAuthnContextClassRef(AuthnContext.PASSWORD_AUTHN_CTX);
authContext.setAuthnContextClassRef(authCtxClassRef);
authStmt.setAuthnContext(authContext);
samlAssertion.getAuthnStatements().add(authStmt);
if (claims != null) {
samlAssertion.getAttributeStatements().add(buildAttributeStatement(claims));
}
AudienceRestriction audienceRestriction =
new AudienceRestrictionBuilder().buildObject();
if (requestedAudiences != null) {
for (String requestedAudience : requestedAudiences) {
Audience audience = new AudienceBuilder().buildObject();
audience.setAudienceURI(requestedAudience);
audienceRestriction.getAudiences().add(audience);
}
}
Conditions conditions = new ConditionsBuilder().buildObject();
conditions.setNotBefore(currentTime);
conditions.setNotOnOrAfter(notOnOrAfter);
conditions.getAudienceRestrictions().add(audienceRestriction);
samlAssertion.setConditions(conditions);
if (doAssertionSigning) {
setSignature(samlAssertion, XMLSignature.ALGO_ID_SIGNATURE_RSA, getCredential());
}
} catch (Exception e) {
e.printStackTrace();
}
return samlAssertion;
}

This[1] is the only library I was able to find related to building SAML Assertions. You can find the source code for the library here [2]. Give it a try to explore it's capabilties. It currently seem to only support SAML 1.1 tokens
[1] https://www.npmjs.com/package/saml
[2] https://github.com/auth0/node-saml

Related

Updating User.UserAttributes on AWS Pinpoint

I cannot seem to update pre-existing UserAttributes on a user "73". I am not sure if this behaviour is to be expected.
Map<String, List<String>> userAttributes = new HashMap<>();
userAttributes.put("Inference", Arrays.asList("NEGATIVE"));
userAttributes.put("Gender", Arrays.asList("M"));
userAttributes.put("ChannelPreference", Arrays.asList("EMAIL"));
userAttributes.put("TwitterHandle", Arrays.asList("Nutter"));
userAttributes.put("Age", Arrays.asList("435"));
EndpointUser endpointUser = new EndpointUser().withUserId("73");
endpointUser.setUserAttributes(userAttributes);
EndpointRequest endpointRequest = new EndpointRequest().withUser(endpointUser);
UpdateEndpointResult updateEndpointResult = pinpoint.updateEndpoint(new UpdateEndpointRequest()
.withEndpointRequest(endpointRequest).withApplicationId("380c3902d4ds47bfb6f9c6749c6dc8bf").withEndpointId("a1fiy2gy+eghmsadj1vqew6+aa"));
System.out.println(updateEndpointResult.getMessageBody());
#David.Webster,
You can update user-attributes of Amazon Pinpoint endpoint using the below Java code snippet which I have tested to be working :
public static void main(String[] args) throws IOException {
// Try to update the endpoint.
try {
System.out.println("===============================================");
System.out.println("Getting Started with Amazon Pinpoint"
+"using the AWS SDK for Java...");
System.out.println("===============================================\n");
// Initializes the Amazon Pinpoint client.
AmazonPinpoint pinpointClient = AmazonPinpointClientBuilder.standard()
.withRegion(Regions.US_EAST_1).build();
// Creates a new user definition.
EndpointUser jackchan = new EndpointUser().withUserId("73");
// Assigns custom user attributes.
jackchan.addUserAttributesEntry("name", Arrays.asList("Jack", "Chan"));
jackchan.addUserAttributesEntry("Inference", Arrays.asList("NEGATIVE"));
jackchan.addUserAttributesEntry("ChannelPreference", Arrays.asList("EMAIL"));
jackchan.addUserAttributesEntry("TwitterHandle", Arrays.asList("Nutter"));
jackchan.addUserAttributesEntry("gender", Collections.singletonList("M"));
jackchan.addUserAttributesEntry("age", Collections.singletonList("435"));
// Adds the user definition to the EndpointRequest that is passed to the Amazon Pinpoint client.
EndpointRequest jackchanIphone = new EndpointRequest()
.withUser(jackchan);
// Updates the specified endpoint with Amazon Pinpoint.
UpdateEndpointResult result = pinpointClient.updateEndpoint(new UpdateEndpointRequest()
.withEndpointRequest(jackchanIphone)
.withApplicationId("4fd13a407f274f10b4ec06cbc71738bd")
.withEndpointId("095A8688-7D79-43CE-BDCE-7DF713332BC3"));
System.out.format("Update endpoint result: %s\n", result.getMessageBody().getMessage());
} catch (Exception ex) {
System.out.println("EndpointUpdate Failed");
System.err.println("Error message: " + ex.getMessage());
ex.printStackTrace();
}
}
}
Hope this helps

SOAP Fault: Security requirements are not satisfied because the security header is not present in the incoming message

I am trying to integrate salesforce with exacttarget using the SOAP wsdl provided by Exacttarget.
I am able to generate apex classes , but on calling the create request , I get the error System.CalloutException: Web service callout failed.
Since I am new to apex , I am not sure if SOAP header request can be done only through http ? or can I do it through my class.
Please find below the code I am using.
exacttargetComWsdlPartnerapi.Soap soapReq = new exacttargetComWsdlPartnerapi.Soap();
exacttargetComWsdlPartnerapi.UsernameAuthentication authentication = new exacttargetComWsdlPartnerapi.UsernameAuthentication();
authentication.UserName = '******';
authentication.PassWord = '*****';
soapReq.inputHttpHeaders_x = new Map<String, String>();
soapReq.outputHttpHeaders_x = new Map<String, String>();
//String myData = 'smruti.bhargava#accenture.com.etdev:smruti#123';
//authentication = EncodingUtil.base64Encode(Blob.valueOf(myData));
soapReq.inputHttpHeaders_x.put('Authorization','Basic ' + authentication );SALESFORCE STUB
exacttargetComWsdlPartnerapi.CreateOptions optList = new exacttargetComWsdlPartnerapi.CreateOptions();
exacttargetComWsdlPartnerapi.ContainerID contnr = new exacttargetComWsdlPartnerapi.ContainerID();
exacttargetComWsdlPartnerapi.APIObject apiObj = new exacttargetComWsdlPartnerapi.APIObject();
exacttargetComWsdlPartnerapi.APIProperty apiProp = new exacttargetComWsdlPartnerapi.APIProperty();
List<exacttargetComWsdlPartnerapi.APIProperty> propList = new List<exacttargetComWsdlPartnerapi.APIProperty>();
apiProp.Name='EmailAddress';
apiprop.Value='ash123#gmail.com';
propList.add(apiProp);
apiObj.PartnerProperties=propList;
contnr.APIObject = apiObj;
optList.Container = contnr;
List<exacttargetComWsdlPartnerapi.APIObject> objList = new List<exacttargetComWsdlPartnerapi.APIObject>();
objList.add(apiObj);
exacttargetComWsdlPartnerapi.CreateResponse_element response = soapReq.Create(optList,objList);
System.debug('** Result ==>' + response);

OAuth making requests against LinkedIn API cause 401 error

I am creating an application for a client that integrates with the LinkedIn API. I got through the authentication without too many problems, but everything there is working and now I need to make the actual requests. Primarily I am working in the Share API. I create the HTTP call with the following method:
public any function sendRequest(any req){
var param = false;
var headParams = [];
var bodyParams = [];
var call = new http(proxyserver='192.168.201.12', proxyport=8888);
var i = 1;
call.setUrl(Arguments.req.getRequestUrl());
call.setMethod(Arguments.req.getMethod());
getSigner().signRequest(Arguments.req);
headParams = Arguments.req.getParameters(true);
bodyParams = Arguments.req.getParameters();
if(arrayLen(bodyParams)){
call.addParam(
type='header',
name='Authorization',
value="OAuth#Variables.encoder.encodedParameter(Arguments.req.getParameters(true), true, false, true)#"
);
}
// Header parameters
if(!arrayLen(bodyParams)){
for(i=1; i<=arrayLen(headParams); i++){
param = headParams[i];
call.addParam(
type=Arguments.req.getParameterType(),
name=Variables.encoder.parameterEncodedFormat(param.name),
value=param.value
);
}
}
// Body parameters (should only be 1)
if(arrayLen(bodyParams)){
for(i=1; i<=arrayLen(bodyParams); i++){
param = bodyParams[i];
call.addParam(
type='xml',
value=param.value
);
}
}
return call.send().getPrefix();
}
When I sign the request, I use the following method:
public void function signRequest(any req){
var headParams = Arguments.req.getParameters(true);
var bodyParams = Arguments.req.getParameters();
var secret = "#Variables.encoder.parameterEncodedFormat(getConsumer().getConsumerSecret())#&#Variables.encoder.parameterEncodedFormat(Arguments.req.getOAuthSecret())#";
var base = '';
params = Variables.encoder.encodedParameter(headParams, true, true);
params = "#params#&#Variables.encoder.parameterEncodedFormat(bodyParams[1].value)#";
secret = toBinary(toBase64(secret));
local.mac = createObject('java', 'javax.crypto.Mac').getInstance('HmacSHA1');
local.key = createObject('java', 'javax.crypto.spec.SecretKeySpec').init(secret, local.mac.getAlgorithm());
base = "#Arguments.req.getMethod()#&";
base = base & Variables.encoder.parameterEncodedFormat(Arguments.req.getRequestUrl());
base = "#base#&#Variables.encoder.parameterEncodedFormat(params)#";
//writeDump(base) abort;
local.mac.init(local.key);
local.mac.update(JavaCast('string', base).getBytes());
Arguments.req.addParameter('oauth_signature', toString(toBase64(mac.doFinal())), true);
}
I have tried signing it with only the header parameters (usual OAuth params) and include the body parameter (xml string), but everything gives me a 401 error, so I was wondering what I should be using in my base string that gets signed for the request?
Not a proper answer to your question, but may help you.
In my case after many unsuccessful tries of using the LinkedIn API with CF8, I finally gave up / didn't have more time for it. Instead of a "proper" integration I've used the linkedin-j Java library. It finally got me going and I didn't encounter any more signing issues.
Btw for all my integrations requiring OAuth I've used this library and didn't have any signing issues as with LinkedIn API.

openid4java ConsumerManager request/thread safe?

I am using openid4java in servlets. I have two servlets - one which performs first step (redirects user to login/accept application access) and second, which processes resulting information
In the documentation, there is written, that org.openid4java.consumer.ConsumerManager class must be the same instance in both steps. Can I create singleton for that? Is it thread and request safe?
Thanks for your replies!
In the consumer servlet from official openid4java sample it seems that ConsumerManager is thread safe - they use single ConsumerManager instance for all sessions. I use it this way too and have not noticed any strange behaviour yet. But a javadoc statement about thread-safety from the developers would be great...
//Currently only working with google only
// Try this - this is all ine one..
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//import org.jboss.web.tomcat.security.login.WebAuthentication;
import org.openid4java.OpenIDException;
import org.openid4java.consumer.ConsumerException;
import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.VerificationResult;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.discovery.Identifier;
import org.openid4java.message.AuthRequest;
import org.openid4java.message.AuthSuccess;
import org.openid4java.message.ParameterList;
import org.openid4java.message.ax.AxMessage;
import org.openid4java.message.ax.FetchRequest;
import org.openid4java.message.ax.FetchResponse;
public class OpenAuth extends javax.servlet.http.HttpServlet {
final static String YAHOO_ENDPOINT = "https://me.yahoo.com";
final static String GOOGLE_ENDPOINT = "https://www.google.com/
accounts/o8/id";
//Updated version of example code from :
https://crisdev.wordpress.com/2011/03/23/openid4java-login-example/
//Add your servlet script path here - so if auth fails or
succeeds it will carry out actions - check below in doGet
public String scr="/servlets/MyServlet";
private ServletContext context;
private ConsumerManager manager;
private ConsumerManager mag;
//Code updated by Vahid Hedayati http://pro.org.uk
//Removed config init - moved post to doGet - since previous code
required it to be a post but also to include identifier as part of
url
//identifier was also the same variable used for Identifier code -
//cleaned up to make different variable and less confusion
//doGet identifer changed to openid_identifier and it also now looks
for openid_username which are the default variables returned from
openid-selector
//http://groups.google.com/group/openid4java/browse_thread/thread/
5e8f24f51f54dc2c
//After reading above post - store the manager in the session object
and failing with Yahoo authentication I changed code for the manager
//manage
public void doPost(HttpServletRequest req,HttpServletResponse
response) throws ServletException,IOException {
doGet(req, response);
}
protected void doGet(HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException {
//New variable
String ouser=(String)req.getParameter("openid_username");
if (ouser==null) { ouser="";}
//Mage is the session value of openid_consumer_manager if it is
null it will generate it once
//And where ever manager is called within code it first returns
managers value by looking up session value
mag=(ConsumerManager)req.getSession().getAttribute("open_id_consumer_manager");
if (mag==null) {
this.manager = new ConsumerManager();
req.getSession().setAttribute("open_id_consumer_manager", manager);
}
String identify=(String)req.getParameter("openid_identifier");
if (identify==null) { identify="";}
if (!identify.equals("")) {
this.authRequest(identify,ouser, req, resp);
}else{
//If they have succeeded it will return them to welcome
//welcome looks up if NEWUSER = yes in the session value below
and if so
//scr now has the ip city/country/postcode so it finalises
user additiion by adding users ip country/city/ip as their sign up
// if not new well they are already logged in from the
relevant session values this code has put in so updats records and
returns they my accoount
//if authentication here failed or they rejected sharing their
email then login page is returned
Identifier identifier = this.verifyResponse(req);
if (identifier != null) {
resp.sendRedirect(scr+"?act=welcome");
} else {
resp.sendRedirect(scr+"?act=login");
}
}
}
// --- placing the authentication request ---
public String authRequest(String userSuppliedString,String Ouser,
HttpServletRequest httpReq, HttpServletResponse httpResp) throws
IOException {
try {
// configure the return_to URL where your application will
receive
// the authentication responses from the OpenID provider
String returnToUrl = httpReq.getRequestURL().toString();
// --- Forward proxy setup (only if needed) ---
// ProxyProperties proxyProps = new ProxyProperties();
// proxyProps.setProxyName("proxy.example.com");
// proxyProps.setProxyPort(8080);
// HttpClientFactory.setProxyProperties(proxyProps);
// perform discovery on the user-supplied identifier
//Modified - Look up manager value from session
manager = (ConsumerManager)
httpReq.getSession().getAttribute("open_id_consumer_manager");
List discoveries = manager.discover(userSuppliedString);
// attempt to associate with the OpenID provider
// and retrieve one service endpoint for authentication
DiscoveryInformation discovered =
manager.associate(discoveries);
// store the discovery information in the user's session
httpReq.getSession().setAttribute("openid-disc", discovered);
// obtain a AuthRequest message to be sent to the OpenID
provider
AuthRequest authReq = manager.authenticate(discovered,
returnToUrl);
FetchRequest fetch = FetchRequest.createFetchRequest();
if (userSuppliedString.startsWith(GOOGLE_ENDPOINT)) {
fetch.addAttribute("email", "http://axschema.org/
contact/email", true);
fetch.addAttribute("firstName", "http://axschema.org/
namePerson/first", true);
fetch.addAttribute("lastName", "http://axschema.org/
namePerson/last", true);
} else if (userSuppliedString.startsWith(YAHOO_ENDPOINT)) {
fetch.addAttribute("email", "http://axschema.org/
contact/email", true);
fetch.addAttribute("fullname", "http://axschema.org/
namePerson", true);
} else {
// works for myOpenID
fetch.addAttribute("fullname", "http://
schema.openid.net/namePerson", true);
fetch.addAttribute("email", "http://schema.openid.net/
contact/email", true);
}
httpReq.getSession().setAttribute("Ouser",Ouser);
// attach the extension to the authentication request
authReq.addExtension(fetch);
httpResp.sendRedirect(authReq.getDestinationUrl(true));
} catch (OpenIDException e) {
// present error to the user
}
return null;
}
// --- processing the authentication response ---
public Identifier verifyResponse(HttpServletRequest httpReq) {
try {
// extract the parameters from the authentication response
// (which comes in as a HTTP request from the OpenID provider)
ParameterList response = new
ParameterList(httpReq.getParameterMap());
// retrieve the previously stored discovery information
DiscoveryInformation discovered = (DiscoveryInformation)
httpReq.getSession().getAttribute("openid-disc");
// extract the receiving URL from the HTTP request
StringBuffer receivingURL = httpReq.getRequestURL();
String queryString = httpReq.getQueryString();
if (queryString != null && queryString.length() > 0)
receivingURL.append("?").append(httpReq.getQueryString());
// verify the response; ConsumerManager needs to be the same
// (static) instance used to place the authentication request
//Modified - look up session value before running verification
result
manager = (ConsumerManager)
httpReq.getSession().getAttribute("open_id_consumer_manager");
VerificationResult verification =
manager.verify(receivingURL.toString(), response, discovered);
// examine the verification result and extract the verified
// identifier
Identifier verified = verification.getVerifiedId();
String id=verified.getIdentifier();
if (verified != null) {
AuthSuccess authSuccess = (AuthSuccess)
verification.getAuthResponse();
if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
FetchResponse fetchResp = (FetchResponse)
authSuccess.getExtension(AxMessage.OPENID_NS_AX);
List emails =
fetchResp.getAttributeValues("email");
String email = (String) emails.get(0);
////////////////////////////////////////////////////////////////////////////////
//Custom bit each person needs to implement to
interact with their application:
//Authenticate the user, send email verify if
user exists on local system
//If it does {
//
httpReq.getSession().setAttribute("USERNAME",usern);
httpReq.getSession().setAttribute("LOGGEDIN", "on");
//}else{
String firstName =
fetchResp.getAttributeValue("firstName");
String lastName =
fetchResp.getAttributeValue("lastName");
String
fullname=fetchResp.getAttributeValue("fullname");
if (fullname==null)
{fullname="";}
if (firstName==null)
{ firstName="";}
if (lastName==null) { lastName="";}
if (!fullname.equals("")) {
if (fullname.indexOf(",")>-1)
{
firstName=fullname.substring(0,fullname.indexOf(","));
lastName=fullname.substring(fullname.indexOf(","),fullname.length());
}else if (fullname.indexOf("
")>-1){
firstName=fullname.substring(0,fullname.indexOf(" "));
lastName=fullname.substring(fullname.indexOf(" "),fullname.length());
}
}
//This is username returned
from the various services that ask for a username - it is returned as
openid_username
//When using openid-selector it uses
openid_identifier and openid_username - which is what this program now
looks for
String
ouser=(String)httpReq.getSession().getValue("Ouser");
if (ouser==null) {ouser="";}
//Adduser -- pass email address and
ouser
//In Adduser class - if ouser is blank
split email from 0 to substring.indexOf("#")
// generate a random number - look up
current user - if exist add random number to end
//and add user with email and new
username
//return bac the newuser and log in
like above.
httpReq.getSession().setAttribute("NEWUSER","YES");
//
httpReq.getSession().setAttribute("USERNAME",usern);
httpReq.getSession().setAttribute("LOGGEDIN", "on");
//}
return verified; // success
}
}
} catch (OpenIDException e) {
// present error to the user
}
return null;
}

Using the Reporting Services Web Service, how do you get the permissions of a particular user?

Using the SQL Server Reporting Services Web Service, how can I determine the permissions of a particular domain user for a particular report? The user in question is not the user that is accessing the Web Service.
I am accessing the Web Service using a domain service account (lets say MYDOMAIN\SSRSAdmin) that has full permissions in SSRS. I would like to programmatically find the permissions of a domain user (lets say MYDOMAIN\JimBob) for a particular report.
The GetPermissions() method on the Web Service will return a list of permissions that the current user has (MYDOMAIN\SSRSAdmin), but that is not what I'm looking for. How can I get this same list of permissions for MYDOMAIN\JimBob? I will not have the user's domain password, so using their credentials to call the GetPermissions() method is not an option. I am however accessing this from an account that has full permissions, so I would think that theoretically the information should be available to it.
SSRS gets the NT groups from the users' NT login token. This is why when you are added to a new group, you are expected to log out and back in. The same applies to most Windows checks (SQL Server, shares, NTFS etc).
If you know the NT group(s)...
You can query the ReportServer database directly. I've lifted this almost directly out of one of our reports which we use to check folder security (C.Type = 1). Filter on U.UserName.
SELECT
R.RoleName,
U.UserName,
C.Path
FROM
ReportServer.dbo.Catalog C WITH (NOLOCK) --Parent
JOIN
ReportServer.dbo.Policies P WITH (NOLOCK) ON C.PolicyID = P.PolicyID
JOIN
ReportServer.dbo.PolicyUserRole PUR WITH (NOLOCK) ON P.PolicyID = PUR.PolicyID
JOIN
ReportServer.dbo.Users U WITH (NOLOCK) ON PUR.UserID = U.UserID
JOIN
ReportServer.dbo.Roles R WITH (NOLOCK) ON PUR.RoleID = R.RoleID
WHERE
C.Type = 1
look into "GetPolicies Method" you can see at the following link.
http://msdn.microsoft.com/en-us/library/reportservice2010.reportingservice2010.getpolicies.aspx
Hopefully this will get you started. I use it when copying Folder structure, and Reports from an old server to a new server when I want to 'migrate' my SSRS items from the Source to the Destination Server. It is a a Method to Get the Security Policies for an item on one server, and then set the Security Policies for an identical item on another server, after I have copied the item from the Source Server to the Destination Server. You have to set your own Source and Destination Server Names.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Web.Services.Protocols; //<=== required for SoapException
namespace SSRS_WebServices_Utility
{
internal static class TEST
{
internal static void GetPoliciesForAnItem_from_Source_ThenSetThePolicyForTheItem_on_Destination(string itemPath)
{
string sSourceServer = "SOURCE-ServerName";
Source_ReportService2010.ReportingService2010 sourceRS = new Source_ReportService2010.ReportingService2010();
sourceRS.Credentials = System.Net.CredentialCache.DefaultCredentials;
sourceRS.Url = #"http://" + sSourceServer + "/reportserver/reportservice2010.asmx";
string sDestinationServer = "DESTINATION-ServerName";
Destination_ReportService2010.ReportingService2010 DestinationRS = new Destination_ReportService2010.ReportingService2010();
DestinationRS.Credentials = System.Net.CredentialCache.DefaultCredentials;
DestinationRS.Url = #"http://" + sDestinationServer + "/reportserver/reportservice2010.asmx";
Boolean val = true;
Source_ReportService2010.Policy[] curPolicy = null;
Destination_ReportService2010.Policy[] newPolicy = null;
try
{
curPolicy = new Source_ReportService2010.Policy[1];
curPolicy = sourceRS.GetPolicies(itemPath, out val); //e.g. of itemPath: "/B2W/001_OLD_PuertoRicoReport"
//DestinationRS.SetPolicies(itemPath, newPolicy);
int iCounter = 0;
//int iMax = curPolicy.Length;
newPolicy = new Destination_ReportService2010.Policy[curPolicy.Length];
foreach (Source_ReportService2010.Policy p in curPolicy)
{
//create the Policy
Destination_ReportService2010.Policy pNew = new Destination_ReportService2010.Policy();
pNew.GroupUserName = p.GroupUserName;
pNew.GroupUserName = p.GroupUserName;
Destination_ReportService2010.Role rNew = new Destination_ReportService2010.Role();
rNew.Description = p.Roles[0].Description;
rNew.Name = p.Roles[0].Name;
//create the Role, which is part of the Policy
pNew.Roles = new Destination_ReportService2010.Role[1];
pNew.Roles[0]=rNew;
newPolicy[iCounter] = pNew;
iCounter += 1;
}
DestinationRS.SetPolicies(itemPath, newPolicy);
Debug.Print("whatever");
}
catch (SoapException ex)
{
Debug.Print("SoapException: " + ex.Message);
}
catch (Exception Ex)
{
Debug.Print("NON-SoapException: " + Ex.Message);
}
finally
{
if (sourceRS != null)
sourceRS.Dispose();
if (DestinationRS != null)
DestinationRS.Dispose();
}
}
}
}
To invoke it use the following:
TEST.GetPoliciesForAnItem_from_Source_ThenSetThePolicyForTheItem_on_Destination("/FolderName/ReportName");
Where you have to put your own SSRS Folder Name and Report Name, i.e. the Path to the item.
In fact I use a method that loops through all the items in the Destination folder that then calls the method like this:
internal static void CopyTheSecurityPolicyFromSourceToDestinationForAllItems_2010()
{
string sDestinationServer = "DESTINATION-ServerName";
Destination_ReportService2010.ReportingService2010 DestinationRS = new Destination_ReportService2010.ReportingService2010();
DestinationRS.Credentials = System.Net.CredentialCache.DefaultCredentials;
DestinationRS.Url = #"http://" + sDestinationServer + "/reportserver/reportservice2010.asmx";
// Return a list of catalog items in the report server database
Destination_ReportService2010.CatalogItem[] items = DestinationRS.ListChildren("/", true);
// For each FOLDER, debug Print some properties
foreach (Destination_ReportService2010.CatalogItem ci in items)
{
{
Debug.Print("START----------------------------------------------------");
Debug.Print("Object Name: " + ci.Name);
Debug.Print("Object Type: " + ci.TypeName);
Debug.Print("Object Path: " + ci.Path);
Debug.Print("Object Description: " + ci.Description);
Debug.Print("Object ID: " + ci.ID);
Debug.Print("END----------------------------------------------------");
try
{
GetPoliciesForAnItem_from_Source_ThenSetThePolicyForTheItem_on_Destination(ci.Path);
}
catch (SoapException e)
{
Debug.Print("SoapException START----------------------------------------------------");
Debug.Print(e.Detail.InnerXml);
Debug.Print("SoapException END----------------------------------------------------");
}
catch (Exception ex)
{
Debug.Print("ERROR START----------------------------------------------------");
Debug.Print(ex.GetType().FullName);
Debug.Print(ex.Message);
Debug.Print("ERROR END----------------------------------------------------");
}
}
}
}