Get definite schema information for Microsoft Graph requests - ms-office

I have an Office JavaScript add-in. We handle our own license workflow. Part of the workflow is to use office-js-helpers to handle Microsoft logging. The user uses the Microsoft endpoint to log in and we receive an access token which we send to https://graph.microsoft.com/v1.0/me to retrieve user data. Some users are individual Microsoft users, others are part of an organization.
Recently, I've noticed that the givenName field is not provided, and it's causing errors in ingestion. I find it hard to design a schema to handle user data coming from MS Graph, since I have not seen any schema information for the possible responses to me request.
Can someone point me to where MS lists the definite schema for it's Graph requests? Is there a request URI for that kind of info?

The underlying object schema could be determined by specifying odata=fullmetadata JSON control level as demonstrated below:
Url: https://graph.microsoft.com/v1.0/me
Method: Get
Headers
Accept: application/json;odata.metadata=full;odata.streaming=false;IEEE754Compatible=false
which returns the type name of the containing object (odata.type annotation), in case of https://graph.microsoft.com/v1.0/me endpoint it is #microsoft.graph.user
And then via Microsoft Graph API metadata endpoint:
Url: https://graph.microsoft.com/v1.0/$metadata
Method: Get
where microsoft.graph.user entity schema could be found under under Schema element for Namespace="microsoft.graph":
<EntityType Name="user" BaseType="microsoft.graph.directoryObject" OpenType="true">
<Property Name="accountEnabled" Type="Edm.Boolean" />
<Property Name="ageGroup" Type="Edm.String" />
<Property Name="assignedLicenses" Type="Collection(microsoft.graph.assignedLicense)" Nullable="false" />
<Property Name="assignedPlans" Type="Collection(microsoft.graph.assignedPlan)" Nullable="false" />
<Property Name="businessPhones" Type="Collection(Edm.String)" Nullable="false" />
<Property Name="city" Type="Edm.String" />
<Property Name="companyName" Type="Edm.String" />
<Property Name="consentProvidedForMinor" Type="Edm.String" />
<Property Name="country" Type="Edm.String" />
<Property Name="department" Type="Edm.String" />
<Property Name="deviceKeys" Type="Collection(microsoft.graph.deviceKey)" Nullable="false" />
<Property Name="displayName" Type="Edm.String" />
<Property Name="employeeId" Type="Edm.String" />
<Property Name="givenName" Type="Edm.String" />
...
</EntityType>

Related

Can't Enforce password reset on WSo2IS?

When I send the SOAP request to update the forcedpasswordreset value i get 202 Code on the SOAP UI and the user doesn't get notified to update the password, and the wso2carbon.log says the following:
INFO {org.wso2.carbon.core.services.util.CarbonAuthenticationUtil} - 'wso2admin#carbon.super [-1234]' logged in at [2019-01-07 11:39:23,318+0200]
I'm trying to use AdminForcedPasswordReset in WSO2 Identity Server and I followed the steps in {https://docs.wso2.com/display/IS530/Forced+Password+Reset} RecoveryEmail type.
Here's my SOAP Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mgt="http://mgt.profile.user.identity.carbon.wso2.org" xmlns:xsd="http://mgt.profile.user.identity.carbon.wso2.org/xsd">
<soapenv:Header/>
<soapenv:Body>
<mgt:setUserProfile>
<mgt:username>omar.alaeldain</mgt:username>
<mgt:profile>
<xsd:fieldValues>
<xsd:claimUri>http://wso2.org/claims/identity/adminForcedPasswordReset</xsd:claimUri>
<xsd:fieldValue>true</xsd:fieldValue>
</xsd:fieldValues>
<xsd:profileName>default</xsd:profileName>
</mgt:profile>
</mgt:setUserProfile>
</soapenv:Body>
I expect the user omar.alaeldain to get nitified at next login by an E-mail to update his password.
Please verify whether you have done the following changes.
You need to enable "Enable Password Reset via Recovery Email" from the below configuration.
https://docs.wso2.com/display/IS530/Forced+Password+Reset?preview=/60494003/60494255/forced-password-reset-residentidp.png
You need to configure "from email address".
Open the output-event-adapters.xml file found in the /repository/conf directory.
Configure the relevant property values for the email server that you need to configure for this service under the tag.
<adapterConfig type="email">
<!-- Comment mail.smtp.user and mail.smtp.password properties to support connecting SMTP servers which use trust
based authentication rather username/password authentication -->
<property key="mail.smtp.from">abcd#gmail.com</property>
<property key="mail.smtp.user">abcd</property>
<property key="mail.smtp.password">xxxx</property>
<property key="mail.smtp.host">smtp.gmail.com</property>
<property key="mail.smtp.port">587</property>
<property key="mail.smtp.starttls.enable">true</property>
<property key="mail.smtp.auth">true</property>
<!-- Thread Pool Related Properties -->
<property key="minThread">8</property>
<property key="maxThread">100</property>
<property key="keepAliveTimeInMillis">20000</property>
<property key="jobQueueSize">10000</property>
</adapterConfig>
Configure email address to the user omar.alaeldain.
once finish all the three steps invoke the soap service.

Nifi 1.5 Untrusted Proxy on cluster

I've done my best to follow: https://pierrevillard.com/2016/11/29/apache-nifi-1-1-0-secured-cluster-setup/
I'm running nifi-1.5.0 and when I go to each of the pages I see an error like: Untrusted proxy CN=nifi-{1-3}.east.companyname.com, OU=NIFI.
I'm using ldap authentication, and just accepting the "invalid" certificate.
I've used an unrelated key-server to generate the keystore/truststore/certs as per the link above.
I also have the
nifi.security.needClientAuth=true
and
nifi.cluster.protocol.is.secure=true
set in the nifi.properties files on all of my nodes
my authorizers file includes entries for all of the nodes like:
<property name="Node Identity 1">CN=nifi-1.east.companyname.com, OU=NIFI</property>
<property name="Node Identity 2">CN=nifi-2.east.companyname.com, OU=NIFI</property>
<property name="Node Identity 3">CN=nifi-3.east.companyname.com, OU=NIFI</property>
Thanks in advance!
I would recommend configuring your authorizer in authorizers.xml to use a CompositeConfigurableUserGroupProvider that has two user group providers:
file-user-group-provider: this will be used to store the identities (certificate DNs) of your cluster nodes
ldap-user-group-provider: for your end users, that will be proxied when the cluster is replicating requests
Configure both of these UserGroupProviders, then configure the CompositeConfigurableUserGroupProvider to use the file-user-group-provider as the "Configurable Provider" and the ldap-user-group-provider as "User Group Provider 1". Here is an example:
<authorizers>
<userGroupProvider>
<identifier>file-user-group-provider</identifier>
<class>org.apache.nifi.authorization.FileUserGroupProvider</class>
<property name="Users File">./conf/users.xml</property>
<property name="Legacy Authorized Users File"></property>
<property name="Initial User Identity 1">CN=nifi-1.east.companyname.com, OU=NIFI</property>
<property name="Initial User Identity 1">CN=nifi-2.east.companyname.com, OU=NIFI</property>
<property name="Initial User Identity 1">CN=nifi-3.east.companyname.com, OU=NIFI</property>
</userGroupProvider>
<userGroupProvider>
<identifier>ldap-user-group-provider</identifier>
<class>org.apache.nifi.ldap.tenants.LdapUserGroupProvider</class>
<!-- ... configure this to match the settings in login-identity-providers.xml ... -->
</userGroupProvider>
<userGroupProvider>
<identifier>composite-configurable-user-group-provider</identifier>
<class>org.apache.nifi.authorization.CompositeConfigurableUserGroupProvider</class>
<property name="Configurable User Group Provider">file-user-group-provider</property>
<property name="User Group Provider 1">ldap-user-group-provider</property>
</userGroupProvider>
<accessPolicyProvider>
<identifier>file-access-policy-provider</identifier>
<class>org.apache.nifi.authorization.FileAccessPolicyProvider</class>
<property name="User Group Provider">composite-configurable-user-group-provider</property>
<property name="Authorizations File">./conf/authorizations.xml</property>
<property name="Initial Admin Identity"></property>
<property name="Legacy Authorized Users File"></property>
<property name="Node Identity 1">CN=nifi-1.east.companyname.com, OU=NIFI</property>
<property name="Node Identity 2">CN=nifi-2.east.companyname.com, OU=NIFI</property>
<property name="Node Identity 3">CN=nifi-3.east.companyname.com, OU=NIFI</property>
</accessPolicyProvider>
<authorizer>
<identifier>managed-authorizer</identifier>
<class>org.apache.nifi.authorization.StandardManagedAuthorizer</class>
<property name="Access Policy Provider">file-access-policy-provider</property>
</authorizer>
</authorizers>
Configure this on each node, then remove users.xml and authorizations.xml and restart NiFi on each node. (This is necessary to create the users.xml and authorizations.xml with your node identities setup to act as proxies, which will not happen if users.xml and authorizations.xml exist with data.) If done correctly, each node should allow the clustered nodes to authenticate using the client certificate (from their keystore.jks) and each node will be authorized to act as proxies, meaning that when an end-user is talking to one cluster, that interaction will be replicated to all nodes in the cluster, which is what you want.
You should be able to set nifi.security.needClientAuth=false. Certificate-based authentication will still work, it just won't be required (i.e., for the initial communication from an end-user to a node, LDAP credentials will be enough).
Hope this helps!
Reference: NiFi Admin Guide

How secured is SSO based on token based authentication?

I am planning to integrate jasper server with my web application as Single Sign on. I went through Jasper Authentication cookbook
and jasper
suggest Token based authentication as one of the solution (as authentication is already done by my web application)
What Jasper suggests is this
you pass the token in specific format (as defined below under tokenFormatMapping) to jasper server
, jasper will authenticate the request.
So valid tokens can be
u=user|r=role1|o=org1|pa1=PA11|pa2=PA21|exp=2001404150601
Invalid token can be
u1=user|r=role1|o=org1|pa1=PA11|pa2=PA21|exp=2001404150601
r=role1|u=user|o=org1|pa1=PA11|pa2=PA21|exp=2001404150601
My question is this really a secured process because as soon hacker knows the pattern, he can simply login to jasper server ?
To me looks like security can be compromised here. Am i missing something here?
<bean class="com.jaspersoft.jasperserver.api.security.externalAuth.wrappers.spring.preauth.JSPreAuthenticatedAuthenticationProvider">
....................
<property name="tokenPairSeparator" value="|" />
<property name="tokenFormatMapping">
<map>
<entry key="username" value="u" />
<entry key="roles" value="r" />
<entry key="orgId" value="o" />
<entry key="expireTime" value="exp" />
<entry key="profile.attribs">
<map>
<entry key="profileAttrib1" value="pa1" />
<entry key="profileAttrib2" value="pa2" />
</map>
</entry>
</map>
</property>
<property name="tokenExpireTimestampFormat" value="yyyyMMddHHmmssZ" />
</bean>
</property>
</bean>
According to the Jasper Reports Authentication cookbook, using token-based authentication the user is not directly logged in, meaning that only certain operations can be done using this method.
Furthermore, it specifies the following:
JasperReports Server will accept any properly formatted token;
therefore, you need to protect the integrity of the token using
measures such as the following:
Connect to JasperReports Server using SSL to protect against token interception.
Encrypt the token to protect against tampering.
Configure the token to use a timestamp to protect against replay attacks. Without a timestamp, when you include the token in a web page or REST web service URL, the URL can be copied and used by unauthorized people or systems. Setting the expire time for the token will stop tokens/URLs from being used to authenticate beyond the indicated time. You can set the expiry time depending on your use case. For a user who is logged into the application/portal and is requesting access to JasperReports Server, expiry time of a minute or less from the request time is appropriate.
All communications need to be made through an SSL tunnel. Otherwise, anyone could establish a connection to your JR server, send tokens and get information from it.
I was also looking to implement token based SSO with Jasper Server and got stuck on exactly the same question. This approach doesn't seem secure to me as the authentication is never denied if the request is properly formatted which is a simple thing to do.
The other alternative (If you are not using CAS or LDAP providers) would be to authenticate based on request as mentioned in section 7.4 "Authentication Based on Request" in the authentication cook-book. Create your own custom authentication provider and configure it in the applicationContext-externalAuth.xml :
<bean id="customAuthenticationManager" class="org.springframework.security.
providers.ProviderManager">
<property name="providers">
<list>
<ref bean="${bean.myCustomProvider}"/>
<ref bean="${bean.daoAuthenticationProvider}"/>
</list>
</property>
</bean>

Spring Integration web service client not signing key for outgoing message

I am currently using Spring Integration web service client and its works fine for web service end point with http call.
Now i am trying to call https end point with signing client key to outgoing messages with server cerificate from cacerts(defaut).We have added server certificate in cacerts and we keep authentication key in separate keysore file to sign/add keys to outgoing messages.Its binding with certificate from cacerts as expected.For sign/add key to the outgoing message alonwith server certificate, I have added below code in Spring Integration xml.
<bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
<property name="location">
<value>classpath:client.jks</value>
</property>
<property name="password" value="test123"/>
</bean>
<bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
<property name="keyStore" ref="keyStore"/>
<property name="privateKeyPassword" value="test123"/>
</bean>
After adding above code, Authentication key is not binding with outbound gateway message and there is no exception also. Please help me what i am missing here.Itneed to add/sign authentication keys from myown keystore file alongwith server certificate. I really appreciate your input on this.
Please refer my final Spring integration xml.
<bean id="xshMessageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory" />
<si:channel id="xshReqChannel" />
<si:channel id="xshResChannel" />
<si:gateway id="xshProvider" service-interface="comm.sd.xshProvider" default-request-channel="xshReqChannel" default-reply-channel="xshResChannel"
/>
<ws:outbound-gateway id="xshProvider"
marshaller="xshMarshaller"
unmarshaller="xshMarshaller"
message-sender="xshMessageSender"
message-factory="xshMessageFactory"
request-channel="xshReqChannel"
reply-channel="xshResChannel"
uri="${xshEndPoint}" />
<bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
<property name="location">
<value>classpath:client.jks</value>
</property>
<property name="password" value="test123"/>
</bean>
<bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
<property name="keyStore" ref="keyStore"/>
<property name="privateKeyPassword" value="test123" />
</bean>
</beans>
Do be honest, I have never done anything similar, but according to the Spring WS Docs you go right way. What you have missed is just a configuration for a XwsSecurityInterceptor bean and it injection to the <ws:outbound-gateway> using interceptor attribute.
Would be great if you do the solution and share it with us to add it to our Samples.

Spring Integration & Retry: Do I need a separate retry bean for each service-activator?

I've got a spring integration pipeline and I've got a number of different service activators that I want to enable retry for.
I want to use the same retry policy (i.e. the number of retries, back-off policy, etc). Can I just have one bean that implements the retry policy and use it for several different service activators, or does each service activator need its own retry bean? In other words, can I just make one bean "retryWithBackupAdviceSession" and set it the request-hadler-advice-chain for several service activators? Or does each one need its own?
Here's an example of the retry policy I'm using.
<bean id="retryWithBackoffAdviceSession" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
<property name="retryTemplate">
<bean class="org.springframework.retry.support.RetryTemplate">
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="2000" /> <!-- 2 seconds -->
<property name="multiplier" value="2" /> <!-- double the wait each time -->
<property name="maxInterval" value="30000"/> <!-- maximum of 30 seconds -->
</bean>
</property>
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="3"/>
</bean>
</property>
</bean>
</property>
<property name="recoveryCallback">
<bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
<constructor-arg ref="myErrorChannel"/>
</bean>
</property>
</bean>
As a follow up-question, if my service activator is running in an executor channel, does it somehow keep track of the retries per-thread? Or is there something I need to do to ensure that there isn't cross-talk between the different threads retrying on different messages on the same thread-safe service activator?
You go right way: the RequestHandlerRetryAdvice is thread-safe, so you can use the same beand from several places.
I had to implement Retry mechanism in my project as well and I created my own implementation.
Retry using AOP
This works like a charm.
You can just annotate your methods with the #Retry annotation, provide some config you want and its done.

Resources