473,513 Members | 2,676 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Per-method role management

I've got a web service where different methods require different roles,
and I'm trying to enforce that now.

I've worked out *one* way of doing things, using
PrincipalPermissionAttribute - but that ends up with a response of 500
rather than a 403.

What's the best way of demanding roles for execution of individual web
methods? Obviously I can write a CheckRole method which sets the
response code appropriately, but then if I'm executing a method which
takes parameters, how do I tell the web method not to write all the
rest of the normal response out? Response.End()?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 21 '05 #1
5 3427
When making a web request over http, the status code 500 is the response
for most exceptions.

You may want to look at the Policy mechanism in WSE 2.0 to enforce
role-based authorization.

http://msdn.microsoft.com/library/de...e2wspolicy.asp

Jon Skeet [C# MVP] wrote:
I've got a web service where different methods require different roles,
and I'm trying to enforce that now.

I've worked out *one* way of doing things, using
PrincipalPermissionAttribute - but that ends up with a response of 500
rather than a 403.

What's the best way of demanding roles for execution of individual web
methods? Obviously I can write a CheckRole method which sets the
response code appropriately, but then if I'm executing a method which
takes parameters, how do I tell the web method not to write all the
rest of the normal response out? Response.End()?

Nov 21 '05 #2
<Drew Robbins <"drew at drewby.com">> wrote:
When making a web request over http, the status code 500 is the response
for most exceptions.
Yes - it shouldn't be for this condition though :(
You may want to look at the Policy mechanism in WSE 2.0 to enforce
role-based authorization.

http://msdn.microsoft.com/library/de...ary/en-us/dnws
e/html/wse2wspolicy.asp


Right. I've been trying to avoid all of that stuff for the moment
(partly because I'm using the Compact Framework to talk to the
webservice, so I want to keep things simple).

I think I'll just work out some way of returning normally from the
method having set the response code, and suppress the content of the
response.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 21 '05 #3

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP***********************@msnews.microsoft.co m...
<Drew Robbins <"drew at drewby.com">> wrote:
When making a web request over http, the status code 500 is the response
for most exceptions.
Yes - it shouldn't be for this condition though :(


To return HTTP code 403 you might have to fail it already in the HttpModule
where you do the digest authentication (I'm not sure if you can hack the web
method somehow to get it to return HTTP 403 (see (*)). Handling it in the
HttpModule *and* also allow declarative permissions in the web methods, you
would have to reflect the web method, see if it has the PrincipalPermission
attribute, then check if the user belongs to the role and then possibly
fail. This is a fair amount of work and you'd be writing similar plumbing
that WSE gives you pretty much out of the box...

A bigger question is is it ok to couple the authentication logic with
transport? This depends largely on your requirements, but in general, HTTP
digest authentication for web services is a dead-end as are all
transport-based authentication schemes. They won't do if you want to
authenticate over other transports, over multiple hops, or have support for
WS-Security. Again, WSE would be the real answer here.

(*) I made a quick experiment with the following code in the web method:

Context.Response.Clear();
Context.Response.StatusCode = 403;
Context.Response.StatusDescription = "Access Denied";
Context.Response.Write("<h2>Access Denied</h2>");
Context.Response.End();

but it just ends up returning error code 500 anyway with a
ThreadAbortException. Most likely the Web Service infrastructure in ASP.NET
does not like you trying to change the HTTP response from within the web
method.
You may want to look at the Policy mechanism in WSE 2.0 to enforce
role-based authorization.

http://msdn.microsoft.com/library/de...ary/en-us/dnws
e/html/wse2wspolicy.asp


Right. I've been trying to avoid all of that stuff for the moment
(partly because I'm using the Compact Framework to talk to the
webservice, so I want to keep things simple).

I think I'll just work out some way of returning normally from the
method having set the response code, and suppress the content of the
response.


As it sometimes happens, trying to keep it simple may end up making things
unnecessarily complicated :)

Regards and YMMV,
Sami
Nov 21 '05 #4
Sami Vaaraniemi <sa**********@pleasejippii.fi> wrote:
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP***********************@msnews.microsoft.co m...
<Drew Robbins <"drew at drewby.com">> wrote:
When making a web request over http, the status code 500 is the response
for most exceptions.
Yes - it shouldn't be for this condition though :(


To return HTTP code 403 you might have to fail it already in the HttpModule
where you do the digest authentication (I'm not sure if you can hack the web
method somehow to get it to return HTTP 403 (see (*)). Handling it in the
HttpModule *and* also allow declarative permissions in the web methods, you
would have to reflect the web method, see if it has the PrincipalPermission
attribute, then check if the user belongs to the role and then possibly
fail. This is a fair amount of work and you'd be writing similar plumbing
that WSE gives you pretty much out of the box...


Yes - unfortunately WSE isn't in the picture at the moment.

I'm getting somewhere setting the HTTP code in the web service, but
still investigating at the moment. Unfortunately, it's fairly hard to
look at what's coming down the wire when I'm testing with a Pocket PC
connected with USB.

If I could very easily and robustly work out what web method was going
to be called (beyond just parsing the URL - doable but slightly flaky,
I suspect) I would put the authorization rules in an XML form
somewhere, akin to how servlets work. Unfortunately I can't see any way
of finding out what method is going to be called programatically before
it *is* called. I may well have missed something though...
A bigger question is is it ok to couple the authentication logic with
transport? This depends largely on your requirements, but in general, HTTP
digest authentication for web services is a dead-end as are all
transport-based authentication schemes. They won't do if you want to
authenticate over other transports, over multiple hops, or have support for
WS-Security. Again, WSE would be the real answer here.
For other situations, you're absolutely right. In this case, a
transport authentication mechanism is fine, although I'd prefer not to
couple the *authorization* mechanism in there.

We're abusing web services in a few ways to make the bandwidth more
reasonable, as this is going over GPRS. Some calls have to be made with
HTTP POST rather than SOAP for that reason.
(*) I made a quick experiment with the following code in the web method:

Context.Response.Clear();
Context.Response.StatusCode = 403;
Context.Response.StatusDescription = "Access Denied";
Context.Response.Write("<h2>Access Denied</h2>");
Context.Response.End();

but it just ends up returning error code 500 anyway with a
ThreadAbortException. Most likely the Web Service infrastructure in ASP.NET
does not like you trying to change the HTTP response from within the web
method.


I think it doesn't mind that - it's the call to End() which causes
problems, by throwing an exception. I'm not sure where it sets the code
to 200 though - if it does that after the web method has executed, I
could have problems. Ah well - I'll keep experimenting.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 21 '05 #5
Jon Skeet [C# MVP] <sk***@pobox.com> wrote:
Ah well - I'll keep experimenting.


Current solution seems to work. Each web method has something like:

if (!CheckRole (...)) return;
or
if (!CheckRole (...)) return null;

CheckRole looks like this:

bool CheckRole(string role)
{
if (!Context.User.Identity.IsAuthenticated)
{
Context.Response.StatusCode = 401;
Context.Response.StatusDescription = "Access Denied";
// Context.Response.SuppressContent = true;
return false;
}
if (!Context.User.IsInRole(role))
{
Context.Response.StatusCode = 403;
Context.Response.StatusDescription = "Forbidden";
// Context.Response.SuppressContent = true;
return false;
}
return true;
}

For some reason, suppressing the content makes the server hang - no
idea why yet. That's a slight pity, but not significantly problematic.

That all seems to work, and has the benefit of allowing anonymous
access for the service description. If anyone knows any way of
improving the above, or why it's awful and should be avoided like the
plague, do let me know :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 21 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
13449
by: Greg Ferris | last post by:
I have read a number of posts with techniques for limiting the max number of characters entered into a textarea, but I'm looking for some advice on how to limit the number of rows and the number of...
0
523
by: roberto3214 | last post by:
Hi Guys, How are you? I have recently begun some testing on IIS 6.0 in regards to an asp.net application. After lots of testing I decided to create a simple 1k page size webpage to find out...
2
1920
by: Kallis | last post by:
Hello, I have the following situation when trying to localize my software: I have BIG solution with about 80 projects. In one of the projects I have a number of dialogs (the dialog project :-)...
4
2737
by: Guadala Harry | last post by:
Is there any way for one Session to remove and update objects in another Session? I seriously doubt it, but thought I'd ask. Here's why: I have some data that is unique per user (or per session -...
2
1085
by: needin4mation | last post by:
Hi, I have to decide between a per device and a per license issue. We have several web services that have functions that use things like LOGON_USER. If I have a per device license, does that mean...
7
2863
by: Randy Yates | last post by:
I'm a complete newbie to postgres so please look the other way if these questions are really stupid. Is it legitimate to have one database per data file? For organizational and backup purposes,...
12
1422
by: bruno at modulix | last post by:
Hi I'm currently playing with some (possibly weird...) code, and I'd have a use for per-instance descriptors, ie (dummy code): class DummyDescriptor(object): def __get__(self, obj,...
32
5764
by: Matias Jansson | last post by:
I come from a background of Java and C# where it is common practise to have one class per file in the file/project structure. As I have understood it, it is more common practice to have many...
9
12187
by: bakxchaixDD | last post by:
I DON'T GET THIS project: Many treadmills output the speed in miles per hour. However, most runners think of their pace in minutes and seconds per mile. Write a program that inputs a decimal...
0
2096
by: raveekumarg | last post by:
hi what is the difference between per seat , per server , per processor and i am new to sql 2000 , pl do explain the same.
0
7380
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7535
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7098
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7523
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5683
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5085
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4745
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
1
798
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
455
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.