Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support sign on without SSO (no SFAuthenticationSession) #209

Closed
sattaman opened this issue Mar 6, 2018 · 16 comments
Closed

Support sign on without SSO (no SFAuthenticationSession) #209

sattaman opened this issue Mar 6, 2018 · 16 comments

Comments

@sattaman
Copy link

sattaman commented Mar 6, 2018

I currently use SSO with my app and SFSafariViewController webviews within my app. In order to support this you recommended hacking the code #182 but have said you may add support in the future? If this is something you could support I'd be very happy!

I'm currently using this library through react-native-app-auth which makes hacking the code tricky!

@sattaman sattaman changed the title Support sign on without SSO Support sign on without SSO (no SFAuthenticationSession) Mar 6, 2018
@WilliamDenniss
Copy link
Member

@sattaman can you share some more detail about your use-case? Do you desire the user to be logged in to the SFSafariViewController, is that why you don't want to use SFAuthenticationSession?

@sattaman
Copy link
Author

sattaman commented Mar 8, 2018

Hi , yes we currently have some functionality only existing within a web app , and rely on the SSO between the app and webview when breaking out to these pages.

Also we are using our own identity server instance, so the SSO popup doesnt make much sense, and may confuse users (our id server domain probably wouldnt mean much to them).

@sandronoel
Copy link

#182 did not resolve my case it still hangs when the application is restarted and the user has been authenticated.

@WilliamDenniss
Copy link
Member

AppAuth is really designed to be used with SSO, and I'm not sure we want to proliferate an SFSafariViewController-only pattern that is counter to this goal.

@sattaman's very specific use-case seems valid, that is, when you are authenticating the user to your own site, and are later opening links in the SFSafariViewController to that same site, and need them to be logged in.

Generally speaking, were it a third-party IdP that was used for login, if the login state was desirable on links that the app opens to that same third-party, I'd recommend simply opening the links in Safari, as that seems like the "correct" way to have a persistent session on iOS, now that SFSafariViewController no longer shares the cookie jar. This is based on the assumption that the user would generally want to be using that third-party in Safari directly as well, and from other apps. Thus, an AppAuth SSO + Safari solution seems to be the most user-friendly.

That said, as mentioned in #182 this kind of thing is possible today in AppAuth. We support have extensible user-agent support, so you can supply your own user-agent implementation with whatever logic you need. Here's a proof-of-concept for how you can use the extensibility of AppAuth to authenticate the user with SFSafariViewController: https://gist.github.com/WilliamDenniss/18f3779b4a310361bb955cf4e534f29c You can include that class directly in your own project, no need to fork or modify AppAuth.

@StevenEWright
Copy link
Collaborator

@iainmcgin @kadikraman Do you have any thoughts on exposing the user agent stuff via react-native-app-auth? I am out of sync on what android’s level of support is for this feature (if any).

@StevenEWright StevenEWright reopened this Jul 12, 2018
@nanumonu
Copy link

nanumonu commented Aug 3, 2018

@WilliamDenniss
Using AppAuth i am trying to skip SFAuthenticationSession/SFSafariViewController. I want it app to go to given redirect url and if application is installed into device it will invoke into else open safari.To work that out I change code and put this line [[UIApplication sharedApplication] openURL:requestURL] before its checking the condition for iOS .11 that is line 91 . its going into the redirect url and opening the app but its not getting token as expected. do you guys have any suggestion

@WilliamDenniss
Copy link
Member

@nanumonu if you just want to use openURL, you don't need to change anything. Just use:

  OIDExternalUserAgentIOSCustomBrowser *externalUserAgent =
      [OIDExternalUserAgentIOSCustomBrowser CustomBrowserSafari];
  appDelegate.currentAuthorizationFlow =
   [OIDAuthState authStateByPresentingAuthorizationRequest:request
                                         externalUserAgent:externalUserAgent
                                                callback:^(OIDAuthState *_Nullable authState, NSError *_Nullable error) 

You can try that with the existing samples.

I can't help you debug "it's not getting the token as expected" unless you provide a little more info than that. If you wish to do this then please also open a new issue to avoid side-tracking this one.

@nanumonu
Copy link

nanumonu commented Aug 4, 2018

@WilliamDenniss
Thanks for your feedback I already tried that method but want should I pass in place of externalUserAgent

@WilliamDenniss
Copy link
Member

OIDExternalUserAgentIOSCustomBrowser *externalUserAgent =
      [OIDExternalUserAgentIOSCustomBrowser CustomBrowserSafari];

Is the user-agent that exclusively uses openURL.

@nanumonu
Copy link

nanumonu commented Aug 4, 2018

@WilliamDenniss

trying to implement on perform the request

externalUserAgent = OIDExternalUserAgentIOSCustomBrowser.customBrowserSafari()

self.currentAuthorizationFlow = OIDAuthState.authState(byPresenting: request, presenting:externalUserAgent, callback: {(_ authState: OIDAuthState?, _ error: Error?) -> Void in

it says Cannot convert value of type 'OIDExternalUserAgentIOSCustomBrowser?' to expected argument type 'UIViewController'

app its getting crash

@WilliamDenniss
Copy link
Member

You're calling the wrong method. OIDExternalUserAgentIOSCustomBrowser isn't a UIViewController, I'd expect you have a compiler error too.

This is the method you're looking for:

/*! @brief Convenience method to create a @c OIDAuthState by presenting an authorization request
and performing the authorization code exchange in the case of code flow requests.
@param authorizationRequest The authorization request to present.
@param externalUserAgent A external user agent that can present an external user-agent request.
@param callback The method called when the request has completed or failed.
@return A @c OIDExternalUserAgentSession instance which will terminate when it
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
*/
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
externalUserAgent:(id<OIDExternalUserAgent>)externalUserAgent
callback:(OIDAuthStateAuthorizationCallback)callback;

Make sure you put the scheme you're trying to open with openURL in your plist too…

@nanumonu
Copy link

nanumonu commented Aug 4, 2018

yeah I already have scheme in plist to openURL

I am not exactly sure what point are u saying here is my code

let clientID = “xxxxxxxxx”
let clientSecret = "xxxxxxxxx"
let authorizationEndpoint = URL (string: "xxxxxxxxx")
let tokenEndpoint = URL (string: "xxxxxxxxx")
let redirectURL = URL (string: "com.xxxxxxxxx")

var token: String?
var userInfo: JsonDocument?
var authState: OIDAuthState?
let session = URLSession(configuration: .ephemeral)
var currentAuthorizationFlow: OIDAuthorizationFlowSession?
var externalUserAgent: OIDExternalUserAgentSession?

func authenticate(from presentVC: UIViewController, onCompletion: @escaping (_ status: Bool, _ error: Error?) -> Void) {
    let configuration = OIDServiceConfiguration(authorizationEndpoint: authorizationEndpoint!, tokenEndpoint: tokenEndpoint!
    let request = OIDAuthorizationRequest(configuration: configuration,
                                          clientId: clientID,
                                          clientSecret: clientSecret,
                                          scopes: [OIDScopeOpenID  ,OIDScopeEmail,OIDScopeAddress,OIDScopePhone,OIDScopeProfile],
                                          redirectURL: oAuthURL!,
                                          responseType: OIDResponseTypeCode,
               
                                          additionalParameters: nil)


   currentAuthorizationFlow = OIDAuthState.authState(byPresenting: request, presenting: presentVC, callback: {(_ authState: OIDAuthState?, _ error: Error?) -> Void in
        
        if let state = authState {
            if let aToken = state.lastTokenResponse?.accessToken {
                print("Got authorization tokens. Access token: \(aToken)")
                self.token = aToken
            }

            self.authState = state
            onCompletion(true, nil)

        } else {
            print("Authorization error: \(error?.localizedDescription ?? "")")
            self.authState = nil
            onCompletion(false, error)
        }
    })

my purpose is if their is app into device it should directly open into the app rather then going into safari

@WilliamDenniss
Copy link
Member

WilliamDenniss commented Aug 6, 2018

@nanumonu this is really off-topic for this issue, can you open a new issue with your question, should you wish?

@nanumonu
Copy link

nanumonu commented Aug 6, 2018

@WilliamDenniss
sure

@denisw
Copy link

denisw commented Oct 26, 2018

I created #325, which if merged would allow the use of SFSafariViewController. I really need this to implement identity provider logout (opening a logout web page that clears the browser session) across iOS versions.

@WilliamDenniss
Copy link
Member

You can do this already in AppAuth with an extra snippet of code (no forking needed), see my comment here:
#209 (comment)

@openid openid locked and limited conversation to collaborators Oct 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants