Tuesday, March 27, 2012

Forms authentication problems

Hi,
I'm implementing a custom security extension for Reporting Services,
based on the forms authentication sample, and am having a couple of
problems with authentication.
Here's some background on my set-up.
- We intend to expose reports to our customers over the internet.
Since we already have a main web application with a logon form and
authentication framework, we are sharing the authentication cookies
with that application (which lives on a different server), according
to the MSDN article 'Forms Authentication Across Applications'.
- I have implemented an authentication extension which uses this
framework to authenticate users, and it works. (I can call LogonUser
and get a cookie back if my credentials are valid, among other things.)
- Rather than having a separate logon form for Reporting Services, we
want to redirect users to/from our main logon form on the other server.
First problem: Report Manager isn't redirecting to the logon page that I
specified in the RSWebApplication.config file. Instead it is trying to
call the web service when not authenticated, and failing. (It gets
redirected to the logon page, and doesn't know what to do with it.)
The UFAIRS article doesn't say how RM works out whether the user has
an authentication cookie for the web service which needs forwarding.
Presumably it looks for one in the request, and redirects to the logon
page if the cookie isn't there. But how does it know what the cookie's
called? How does it even know that the web service is using forms
authentication (without first trying it)?
I don't know how what I'm doing is any different to the sample, which
does work. The only thing I've changed (in the Report Manager
configuration) is the loginUrl element within CustomAuthenticationUI,
but RM isn't even trying to redirect the client.
I'm also getting what I think is the same problem using Report Designer
in Visual Studio. When the sample was installed, Report Designer would
pop up a box asking for username and password whenever it tried to use
the web service, but now it just gives me an error message stating "a
connection could not be made to the report server". Again, I'm not sure
how it's trying to determine what it has to do to authenticate itself.
Second problem: redirection from the web service works, but it isn't
respecting the useFullyQualifiedRedirectUrl setting in web.config
(attribute of the httpRuntime element), which I've set to 'true'. The
URL it generates and puts in the query string is relative to the local
server root. Since my logon page is on a different server, I need it to
include the full URL.
Sorry for the long post, and thanks for reading if you got this far.
Please let me know any ideas you might have. I can post details from my
configuration files on request, and please ask if there's something I
haven't made clear. Thanks.
StephenThe name of the authentication cookie is configured in web.config under the
<forms> tag.
Perhaps you can make a call SOAP to LogonUser from your application before
the user gets to report manager. Then send the cookie to the client. Further
access to report server should be authenticated. For report manager to work
in this configuration you need to set the AllowPassthroughCookies - see the
SP1 readme for the exact name.
--
Tudor Trufinescu
Dev Lead
Sql Server Reporting Services
This posting is provided "AS IS" with no warranties, and confers no rights.
"Stephen Kell" <skell@.opaltelecom.co.uk> wrote in message
news:pan.2004.08.04.15.24.00.797000@.opaltelecom.co.uk...
> Hi,
> I'm implementing a custom security extension for Reporting Services,
> based on the forms authentication sample, and am having a couple of
> problems with authentication.
> Here's some background on my set-up.
> - We intend to expose reports to our customers over the internet.
> Since we already have a main web application with a logon form and
> authentication framework, we are sharing the authentication cookies
> with that application (which lives on a different server), according
> to the MSDN article 'Forms Authentication Across Applications'.
> - I have implemented an authentication extension which uses this
> framework to authenticate users, and it works. (I can call LogonUser
> and get a cookie back if my credentials are valid, among other things.)
> - Rather than having a separate logon form for Reporting Services, we
> want to redirect users to/from our main logon form on the other server.
> First problem: Report Manager isn't redirecting to the logon page that I
> specified in the RSWebApplication.config file. Instead it is trying to
> call the web service when not authenticated, and failing. (It gets
> redirected to the logon page, and doesn't know what to do with it.)
> The UFAIRS article doesn't say how RM works out whether the user has
> an authentication cookie for the web service which needs forwarding.
> Presumably it looks for one in the request, and redirects to the logon
> page if the cookie isn't there. But how does it know what the cookie's
> called? How does it even know that the web service is using forms
> authentication (without first trying it)?
> I don't know how what I'm doing is any different to the sample, which
> does work. The only thing I've changed (in the Report Manager
> configuration) is the loginUrl element within CustomAuthenticationUI,
> but RM isn't even trying to redirect the client.
> I'm also getting what I think is the same problem using Report Designer
> in Visual Studio. When the sample was installed, Report Designer would
> pop up a box asking for username and password whenever it tried to use
> the web service, but now it just gives me an error message stating "a
> connection could not be made to the report server". Again, I'm not sure
> how it's trying to determine what it has to do to authenticate itself.
> Second problem: redirection from the web service works, but it isn't
> respecting the useFullyQualifiedRedirectUrl setting in web.config
> (attribute of the httpRuntime element), which I've set to 'true'. The
> URL it generates and puts in the query string is relative to the local
> server root. Since my logon page is on a different server, I need it to
> include the full URL.
> Sorry for the long post, and thanks for reading if you got this far.
> Please let me know any ideas you might have. I can post details from my
> configuration files on request, and please ask if there's something I
> haven't made clear. Thanks.
> Stephen
>|||Firstly, thanks for the reply.
> The name of the authentication cookie is configured in web.config under the
> <forms> tag.
Maybe I misunderstood, but I thought that this was only for the web
service (i.e. in ReportServer/web.config). Report Manager is using Windows
authentication itself, and doesn't have a <forms> element in its
web.config. Let me know if this is not correct.
> Perhaps you can make a call SOAP to LogonUser from your application before
> the user gets to report manager. Then send the cookie to the client. Further
> access to report server should be authenticated. For report manager to work
> in this configuration you need to set the AllowPassthroughCookies - see the
> SP1 readme for the exact name.
Thanks -- I set the PassThroughCookies configuration as required and now I
can access Report Manager. It's still not redirecting in the case of an
unauthenticated request, which would be nice to have working, but not
essential as I can log on using our form first, which generates a valid
cookie. Unfortunately though, I still get the error I described with
Report Designer, and don't have any possibility of working around that
similarly. Please let me know if you have any ideas.
Stephen|||Report manager reads the name of the authentication cookie which is sent by
the report server as an HTTP header.
Unfortunately I don't know of any solution that would allow report designer
to work in this case. As a workaround you could write your own application
that would publish reports using SOAP calls. In the SOAP client, you can
manage your custom cookies as you wish.
--
Tudor Trufinescu
Dev Lead
Sql Server Reporting Services
This posting is provided "AS IS" with no warranties, and confers no rights.
"Stephen Kell" <skell@.opaltelecom.co.uk> wrote in message
news:pan.2004.08.05.14.48.01.766000@.opaltelecom.co.uk...
> Firstly, thanks for the reply.
> > The name of the authentication cookie is configured in web.config under
the
> > <forms> tag.
> Maybe I misunderstood, but I thought that this was only for the web
> service (i.e. in ReportServer/web.config). Report Manager is using Windows
> authentication itself, and doesn't have a <forms> element in its
> web.config. Let me know if this is not correct.
> > Perhaps you can make a call SOAP to LogonUser from your application
before
> > the user gets to report manager. Then send the cookie to the client.
Further
> > access to report server should be authenticated. For report manager to
work
> > in this configuration you need to set the AllowPassthroughCookies - see
the
> > SP1 readme for the exact name.
> Thanks -- I set the PassThroughCookies configuration as required and now I
> can access Report Manager. It's still not redirecting in the case of an
> unauthenticated request, which would be nice to have working, but not
> essential as I can log on using our form first, which generates a valid
> cookie. Unfortunately though, I still get the error I described with
> Report Designer, and don't have any possibility of working around that
> similarly. Please let me know if you have any ideas.
> Stephen
>|||Thanks. I will look into implementing a separate application to deploy
reports.
I am still a bit puzzled about how what I'm doing is substantially
different to the sample -- there's nothing special about my cookies, and
valid cookies can be generated by the RS web service as well as by our own
login page (or at least that's the idea). I'll try to investigate whether
the HTTP requests issued by RM/RD (or the responses they get) are any
different when using the sample, compared to my current installation. (Not
managed to do so yet as I don't currently have a machine with the sample
installed.)
Going back to another issue I mentioned in my first post, I don't suppose
there's any clues about why the web service doesn't generate
fully-qualified redirect URLs? I thought this was all handled by ASP.NET's
underlying FormsAuthentication implementation, but it seems like RS has
altered the normal behaviour, unless I've misunderstood something. Any
suggestions appreciated.
Stephen|||Yes, the redirect in Report manager is done only into the report manager
directory.
--
Tudor Trufinescu
Dev Lead
Sql Server Reporting Services
This posting is provided "AS IS" with no warranties, and confers no rights.
"Stephen Kell" <skell@.opaltelecom.co.uk> wrote in message
news:pan.2004.08.06.15.52.29.703000@.opaltelecom.co.uk...
> Thanks. I will look into implementing a separate application to deploy
> reports.
> I am still a bit puzzled about how what I'm doing is substantially
> different to the sample -- there's nothing special about my cookies, and
> valid cookies can be generated by the RS web service as well as by our own
> login page (or at least that's the idea). I'll try to investigate whether
> the HTTP requests issued by RM/RD (or the responses they get) are any
> different when using the sample, compared to my current installation. (Not
> managed to do so yet as I don't currently have a machine with the sample
> installed.)
> Going back to another issue I mentioned in my first post, I don't suppose
> there's any clues about why the web service doesn't generate
> fully-qualified redirect URLs? I thought this was all handled by ASP.NET's
> underlying FormsAuthentication implementation, but it seems like RS has
> altered the normal behaviour, unless I've misunderstood something. Any
> suggestions appreciated.
> Stephen
>|||(I don't know if anyone's still reading this thread, but if so, I finally
worked out the solution and thought I'd share it.)
Thanks -- it did turn out to be something to do with the redirect
destination being outside of the application's virtual directory, but not
quite what you said. (I won't claim that my explanation matches the
intended logic behind the Reporting Services code, only that it allowed me
to understand and solve the problem I was having.)
In fact, both the RS web service and Report Manager are quite happy to
redirect outside of their virtual directory. The problem is in how their
clients interpret this.
Both Report Manager and Report Designer need some way of determining
whether to call LogonUser. If the web service redirects them to a location
inside its virtual directory, they assume this is a logon page, and do
their ask-for-credentials thing. (For Report Manager it's redirecting to
the page specified in the CustomAuthenticationUI configuration element,
while for Report Designer it's popping up that dialog asking for
credentials.) Once they have the credentials, they call LogonUser to get
their cookie.
If the web service redirects them elsewhere, they don't do any of this,
and instead fall over, in the end generating generic error messages
claiming that the report server isn't working.
I got around this by configuring the web service to redirect to a simple
aspx page (called Logon.aspx, though the name doesn't matter) in its own
virtual directory. In the Page_Load event I test whether a the User-Agent
header was received. This is a bit of magic intended to determine whether
the client is interactive (i.e. a web browser) and therefore capable of
logging in using a form, or not (e.g. a web service client like Report
Designer or Report Manager).
In the case of an interactive client, the page redirects to the (external)
login page. (The URL of the login page is read from a label in the aspx
page, so you don't need to recompile in order to change it.) You must make
sure that you also include the ReturnUrl query string parameter in your
redirect destination URL, *and* that you translate it to a fully-qualified
URL (since RS doesn't seem to do this).
For non-interactive clients, it just serves a blank page (or actually,
since I was feeling helpful, a short message about why the client wasn't
redirected, followed by the aforementioned label showing the login page
URL).
Report Manager and Report Designer now work fine. You can specify the
external login page for RM just like any other.
Sorry for the long-winded explanation -- I hope it proves useful for
someone.
Stephen

No comments:

Post a Comment