I'm trying to develop a simple java client that needs to access Skype for Business APIs in order to setup an online meeting (i.e. I need to retrieve a simple setup meeting URL by invoking an UCWA API).
I followed this Microsoft tutorial step-by-step:
https://learn.microsoft.com/en-us/skype-sdk/ucwa/developingucwaapplicationsforsfbonline
I have an Office 365 Business Premium license and I configured a custom domain (correctly registered and added at the zone DNS file);
I configured and registered my java client app on Azure (taking care to assign required delegated permission for Skype for Business capabilities);
I performed the Sign-in phase and Azure is able to recognize me;
I performed the Autodiscovery phase in order to retrieve the user's UCWA home pool;
I sent a GET request to the Azure oauth2 endpoint with response 401 error (and this is the expected behaviour by the authentication handshake);
Unfortunately, I failed when I request an access token using implicit grant flow: Azure responds with a Sign-In HTML page rather than the json object containing the oauth2 access token.
What's wrong on this GET request?
GET https://login.microsoftonline.com/oauth2/authorize?
response_type=id_token
&client_id=my_application_client_id
&redirect_uri=configured_redirect_uri
&state=UUID_generated_code
&resource=UCWA_home_pool
HTTP/1.1
This GET URL looks like that one used for the Sign-In phase (step 3); I suspect that it isn't the right request URL.
I tryed to put my domain on the URL:
https://login.microsoftonline.com/my_domain_name/oauth2/authorize
and I tryed to put a common domain name (as reported on the documentation):
https://login.microsoftonline.com/common/oauth2/authorize
But Azure still reponds with a Sign-In page (and response code 200 OK).
Can someone help me please?
Please check the oauth2AllowImplicitFlow property in manifest of your application after downloading the latest manifest file. It should be set to true for this to wrok. If it's still false, only then I would expect the redirect to sign-in page as you're seeing.
More detailed steps here -
Configure your app for OAuth implicit grant flow
Related
I have developed MS Teams Message Extension using Java[Spring Boot] and registered the bot in Botframework Development portal[https://dev.botframework.com/]. It is working fine in local. I tested in local environment using a tunneling application named localtunnel. I tested the extension in MS Teams.
I pushed the code to cloud[AWS] as it was working fine on local and also changed the message endpoint URL to point to our test server. But, unfortunately i am getting " Bot returned unsuccessful status code unauthorized."[You can see the screenshot]. Test server message endpoint doesn't require JWT token, I am able to call it successfully from postman with out giving token.
As per the documentation, this error occurs usually when:
The Messaging endpoint specified on the Settings page for your bot in the Bot Framework Portal is incorrect. Make sure you have included the proper path at the end of the URL (e.g., /api/messages).
The Messaging endpoint specified on the Settings page for your bot in the Bot Framework Portal does not begin with https or is not trusted by the Bot Framework. Your bot must have a valid, chain-trusted certificate.
The bot is configured with missing or incorrect values for app ID or password. Verify that the bot configuration settings specify valid values for app ID and password.
All the points are correct in my case.
In this documentation, It is mentioned about Azure Bot resources in the "Test your bot" section of "Step 4: Test your bot in the cloud".
https://learn.microsoft.com/en-us/azure/bot-service/bot-service-troubleshoot-authentication-problems?view=azure-bot-service-4.0&tabs=csharp#step-3
So in order to test the bot on cloud, is it necessary to register it on Azure Bot services instead of Botframework development portal? Can't we just test it just by registering it on Botframework development portal?
The dev.botframework.com portal is deprecated, so I'd advise against continuing to use it. The Azure Bot resource is the evolution and replacement of the Bot Channels Registration, so you will need to use it to test your bot in the cloud. It effectively does the same things, but it better handles various new security and tenancy features that the old portal did not.
Furthermore, the documentation you linked mentions that extra security configuration steps must be taken for non-Azure deployments to get your bot to use https. Ensure you do this before filling in the messaging endpoint in your Azure Bot configuration.
I figure out the issue. Even though message endpoint could be called without any JWT token of our app, code was verifying the token if in case it is present in Authorization header instead of ignoring it. MS Teams sends JWT token in Authorization header of every request to verify it is coming from teams, but extension app was comparing this token sent from teams against our app. Since this token is not created by our app but instead by bot framework, so it was throwing 401 unauthorized.
So make sure your app is in ignoring the token sent in Authorization header for message endpoint.
About the other doubts I had:
It is not mandatory to register bot in azure in order to test in cloud, you can register it in development portal as well. Since development portal is depreciated, I highly recommend to use azure as it is highly secure.
You can do non azure deployment as well. You can deploy your extension app or message API endpoint in any cloud provider of your choice. But you have to register the bot either in development portal or azure which will call your extension app.
From my application I have to invoke external http service which uses google authentication. It works when I invoke it from browser. I found out that it happens because I have cookie which contains
GCP_IAAP_AUTH_TOKEN_<random_string>
GCP_IAP_UID
So my cookie look like this:
cookie: GCP_IAP_UID=111111111111; GCP_IAAP_AUTH_TOKEN_1234567891234567890B=verylongstringhere"
I tried to set this cookie directly in my restTemplate and it works properly but I expect that I have to get token based on some kind of credentials.
webClient.post()
.uri(uploadUrl)
.header("cookie", "GCP_IAP_UID=12345678901234567890; GCP_IAAP_AUTH_TOKEN_12345678907645456546B=verylongstringhere")
Could you please provide example of correct usage GCP auth ? How to update token? Based on what?
Google APIs use the OAuth 2.0 protocol for authentication and authorization
You can obtain OAuth 2.0 client credentials from the Google API Console. Then your client application requests an access token from the Google Authorization Server, extracts a token from the response, and sends the token to the Google API that you want to access.
Before your application can access private data using a Google API, it must obtain an access token that grants access to that API.
There are several ways to make this request, and they vary based on the type of application you are building. For example, a JavaScript application might request an access token using a browser redirect to Google, while an application installed on a device that has no browser uses web service requests.
I recommend you to go trough OAuth 2.0 to Access Google APIs article to choose the best method for your application, there are a couple of documented scenarios to explain how GCP uses application authentication
I have an existing application and all of a sudden i have been given a task to implement IDP initiated SSO. there is a URL to IDP clicking on it asks me to login with IDP provided credentials, after success login the route moves to our application and than my task start to identify the user and give the proper access. I have the certificate provided from our IDP. How can i achieve this? My application is a Spring MVC Java Application.I am using JBOSS AS 7. I havent done a similar thing before. Can anyone please give a step by step clear picture on this? I saw the Spring SAML extension which i couldnt understand properly to get it integrate with my existing app. Any help in this regard will be highly appreciated.
IdP-Initiated SSO
IdP-Initiated SSO with POST Binding
If the user does not have a valid local security context at the IdP, at some point the user will be challenged to supply their credentials to the IdP site, idp.example.org.
The user provides valid credentials and a local logon security context is created for the user at the IdP.
The user selects a menu option or link on the IdP to request access to an SP web site, sp.example.com. This causes the IdP's Single Sign-On Service to be called.
The Single Sign-On Service builds a SAML assertion representing the user's logon security context. Since a POST binding is going to be used, the assertion is digitally signed before it is placed within a SAML message. The message is then placed within an HTML FORM as a hidden form control named SAMLResponse. (If the convention for identifying a specific application resource at the SP is supported at the IdP and SP, the resource URL at the SP is also encoded into the form using a hidden form control named RelayState.) The Single Sign-On Service sends the HTML form back to the browser in the HTTP response. For ease-of-use purposes, the HTML FORM typically will contain script code that will automatically post the form to the destination site.
The browser, due either to a user action or execution of an “auto-submit” script, issues an HTTP POST request to send the form to the SP's Assertion Consumer Service. The service provider's Assertion Consumer Service obtains the message from the HTML FORM for processing. The digital signature on the SAML assertion must first be validated and then the assertion contents are processed in order to create a local logon security context for the user at the SP. Once this completes, the SP retrieves the RelayState data (if any) to determine the desired application resource URL and sends an HTTP redirect response to the browser directing it to access the requested resource (not shown).
An access check is made to establish whether the user has the correct authorization to access the resource. If the access check passes, the resource is then returned to the browser.
See saml-tech-overview-2.0
So if you are implementing the SP, you have to follow the steps 5 and 6 otherwise 1 - 4.
For the implementation you could use OpenSaml if you do not get it working with the Spring SAML extension.
I have a web application that provides several rest services (Jersey). Most of the endpoints are secured by BASIC authentification. Further more I use SSL for transport and demand POSTs for every call.
The clients/consumers are android apps.
So far so good. The only service that seems to be vulnerable is the registration. It's the 'first' service to call and a user does not exist yet. So I cannot use OAuth, etc. I also have to keep the endpoint easy accessible to enable the user to regster.
How do I secure this service, so it's not spammed by a bot flooding my database?
How about these?
Use a registration link with a token in the request parameter. Ensure that the tokens expire after sometime. You could create a token endpoint url as well for a client to get a valid token.
Use a custom header or a dynamic custom header in your request. Additionally, you could check for a dynamic custom header to validate the request's authenticity.
Use registration confirmation workflows, such as an email / text verification as soon the registration is done. Run a process every day to delete any user accounts, which are not validated in say x days.
I do not think you can really secure the registration URL in a HTTP way. IMHO, anyone who has the registration url can be a right guy trying to register. So if you ask me, option 3 is better than others.
I'm attempting to add OAuth support to an existing Spring webapp to allow people to login with their Google/Facebook/Twitter/etc. accounts. To do this I'm using the 'spring-social' framework, and the 'spring-social-google' library for it. I'm also trying to do this while working within a number of constraints:
The existing webapp does not use spring-security for authentication or for controlling access to resources, it provides its own form-based authentication.
The existing webapp does not track the authenticated user details using the servlet-container's Principal, instead it stores a reference to the authenticated user in the HTTP session.
The existing webapp does not (and cannot) have a Spring DispatcherServlet bound to the webapp root URL (i.e. /).
Accounts in the database are uniquely keyed by e-mail, so really all I'm attempting to do is glue together a flow that goes roughly like:
Login Page (user chooses between OAuth and direct login)
-> <Provider OAuth Flow> (user completes OAuth authorization)
-> OAuth Callback URL (grab user email, check for existing account, create if needed)
-> Post-login Landing Page (done)
Anyhow, the limitations noted above caused a variety of problems, most of which I've managed to find workarounds for. However I'm getting some bizarre behavior from the Google OAuth connector (Twitter and Facebook appear to work correctly). Basically, it appears that it is not sending the OAuth clientId or clientSecret during the final request to Google:
DEBUG: org.springframework.web.client.RestTemplate - Writing [
{code=[4/dVVrFDpNLDGTmXCuuQj6fcfaetEU.UkLPQd7NOLYbgrKXntQAax0INYiydQI],
redirect_uri=[http://localhost:8080/oauth/signin/google],
grant_type=[authorization_code]}] as "application/x-www-form-urlencoded"
This returns a code 400 ("bad request").
If I head over to hurl.it and POST the same data to the same URL (https://accounts.google.com/o/oauth2/token) and manually add in the client_id and client_secret values, the call returns a successful response.
So what could be causing the Google connector to omit these values?
For reference, I'm including the spring-social-google library in my project like:
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-google</artifactId>
<version>1.0.0.M1</version>
</dependency>
...and then in my #Configuration class I've got:
#Bean
#Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)
public ConnectionFactoryLocator connectionFactoryLocator() {
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(
new GoogleConnectionFactory(
"<google client id>",
"<google secret key>"));
registry.addConnectionFactory(
new FacebookConnectionFactory(
"<facebook client id>",
"<facebook secret key>"));
registry.addConnectionFactory(
new TwitterConnectionFactory(
"<twitter client id>",
"<twitter secret key>"));
return registry;
}
The rest of what I'm using is pretty much standard straight out of the spring-social-showcase example (albeit hacked up to remove extraneous things and to work within the constraints noted above). Strangely, attempting to log in with Google does correctly show the OAuth authorization page on Google with my app/project name correctly displayed. The error happens after I hit the "Allow" button to authorize the OAuth login and return to the webapp.
Anyhow, what might be causing this issue, and how might it be fixed?
You may not have turned the google+ api on in the google developer console.
This is a separate task from getting an OAuth 2 token or api key.
If you have not done so already
http://console.developers.google.com
Navigate to your project.
Click 'APIs'.
Check 'Google+ API' is in the list of Enabled API's. If it is not, browse for it and enable it.