Related
I would like to get the index values of an indexed image, so that I can modify images in a game where the palette and the index data are separate files. I looked through the command-line options of identify, the -grayscale options, the FX expressions and tried the txt:- output format, but they all don't seem to do the trick.
So if I have an image with a red, a blue, and another red pixel, saved as a GIF with a palette of 0: red and 1: blue, then I'd like to get an output similar to "0 1 0" or "\x00\x01\x00".
If you make a 3-pixel French flag similarly to #xenoid like this:
magick xc:red xc:white xc:blue +append french.gif
You can dump the colormap and pixels using MAP format like this:
magick french.gif map: | xxd
00000000: ff00 0000 00ff ffff ff00 0000 0002 01 ...............
Hopefully you can see the first three bytes are red 0xff 00 00, the next three are blue 0x00 00 ff and the next three are white 0xff ff ff and the last three are indices 0, 2, 1.
If you go Irish, with lime, white and orange:
magick xc:lime xc:white xc:orange +append irish.gif
magick irish.gif map: | xxd
00000000: 00ff 00ff a500 ffff ff00 0000 0002 01 ...............
It may come in handy to know how many colours there are:
identify -format %k irish.gif
3
It may come in handy to use JSON to extract the number of entries in the colormap and their values:
magick irish.gif json: | jq -r '.[].image | .colormapEntries'
4
magick irish.gif json: | jq -r '.[].image | .colormap'
[
"#00FF00FF",
"#FFA500FF",
"#FFFFFFFF",
"#000000FF"
]
Or you can use PIL/Pillow from Python:
python3 -c 'from PIL import Image; print(list(Image.open("irish.gif").getdata()))'
Sample Output
[0, 2, 1]
PIL/Pillow can also output the palette - though you need to be aware that it pads the palette out to 256 entries using shades of grey:
python3 -c 'from PIL import Image; print(list(Image.open("irish.gif").getpalette()))'
[0, 255, 0, 255, 165, 0, 255, 255, 255, 0, 0, 0, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77, 77, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 91, 91, 91, 92, 92, 92, 93, 93, 93, 94, 94, 94, 95, 95, 95, 96, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 119, 119, 119, 120, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 128, 129, 129, 129, 130, 130, 130, 131, 131, 131, 132, 132, 132, 133, 133, 133, 134, 134, 134, 135, 135, 135, 136, 136, 136, 137, 137, 137, 138, 138, 138, 139, 139, 139, 140, 140, 140, 141, 141, 141, 142, 142, 142, 143, 143, 143, 144, 144, 144, 145, 145, 145, 146, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151, 152, 152, 152, 153, 153, 153, 154, 154, 154, 155, 155, 155, 156, 156, 156, 157, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164, 165, 165, 165, 166, 166, 166, 167, 167, 167, 168, 168, 168, 169, 169, 169, 170, 170, 170, 171, 171, 171, 172, 172, 172, 173, 173, 173, 174, 174, 174, 175, 175, 175, 176, 176, 176, 177, 177, 177, 178, 178, 178, 179, 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, 182, 183, 183, 183, 184, 184, 184, 185, 185, 185, 186, 186, 186, 187, 187, 187, 188, 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 194, 194, 194, 195, 195, 195, 196, 196, 196, 197, 197, 197, 198, 198, 198, 199, 199, 199, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205, 206, 206, 206, 207, 207, 207, 208, 208, 208, 209, 209, 209, 210, 210, 210, 211, 211, 211, 212, 212, 212, 213, 213, 213, 214, 214, 214, 215, 215, 215, 216, 216, 216, 217, 217, 217, 218, 218, 218, 219, 219, 219, 220, 220, 220, 221, 221, 221, 222, 222, 222, 223, 223, 223, 224, 224, 224, 225, 225, 225, 226, 226, 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, 230, 230, 230, 231, 231, 231, 232, 232, 232, 233, 233, 233, 234, 234, 234, 235, 235, 235, 236, 236, 236, 237, 237, 237, 238, 238, 238, 239, 239, 239, 240, 240, 240, 241, 241, 241, 242, 242, 242, 243, 243, 243, 244, 244, 244, 245, 245, 245, 246, 246, 246, 247, 247, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251, 251, 251, 252, 252, 252, 253, 253, 253, 254, 254, 254, 255, 255, 255]
If you use IM's convert to convert an image to XPM and get the pixel color indices:
For instance this 9x3 French flag:
Produces this:
/* XPM */
static char *FrenchFlag[] = {
/* columns rows colors chars-per-pixel */
"9 3 3 1 ",
" c #0026FF",
". c #FF2900",
"X c white",
/* pixels */
" XXX...",
" XXX...",
" XXX..."
};
i have an array on Uint8 bytes array and convert them to this unicode text. so i can send it to UDP socket.
bytes array is :
[48, 48, 48, 48, 48, 48, 163, 62, 0, 0, 22, 11, 0, 0, 138, 1, 143, 222, 152, 116, 184, 233, 150, 75, 79, 130, 129, 153, 78, 125, 213, 48, 133, 29, 54, 191, 4, 7, 161, 80, 135, 36, 120, 181, 194, 57, 68, 246, 53, 29, 159, 201, 7, 224, 0, 155, 8, 64, 34, 56, 117, 216, 77, 143, 80, 210, 42, 66, 187, 231, 26, 154, 255, 15, 7, 27, 60, 135, 205, 214, 12, 222, 199, 114, 120, 244, 222, 163, 196, 244, 37, 117, 133, 40, 199, 50, 244, 48, 86, 7, 86, 240, 92, 128, 36, 247, 185, 23, 9, 13, 61, 147, 162, 198, 14, 12, 10, 23, 13, 181, 223, 147, 117, 46, 245, 178, 205, 76, 71, 127, 56, 174, 2, 145, 224, 148, 100, 19, 219, 37, 117, 83, 17, 108, 135, 98, 21, 75, 46, 232, 31, 198, 246, 234, 140, 31, 80, 115, 185, 68, 155, 54, 215, 180, 58, 177, 70, 8, 63, 241, 186, 208, 61, 150, 165, 167, 166, 111, 96, 187, 101, 26, 250, 54, 193, 247, 156, 48, 127, 151, 76, 66, 146, 205, 39, 154, 31, 251, 244, 123, 62, 129, 19, 204, 205, 17, 61, 230, 66, 110, 228, 68, 193, 104, 191, 85, 30, 251, 228, 146, 23, 142, 165, 179, 220, 68, 235, 83, 143, 126, 233, 175, 123, 207, 103, 34, 4, 99, 153, 144, 241, 130, 15, 208, 67, 234, 56, 161, 51, 91, 76, 253, 72, 71, 68, 83, 164, 138, 120, 13, 176, 139, 80, 91, 155, 179, 193, 104, 181, 1, 233, 127, 97, 132, 181, 114, 190, 255, 138, 234, 101, 170, 38, 56, 46, 214, 207, 158, 207, 207, 43, 253, 194, 89, 48, 48, 12, 63, 89, 145, 214, 80, 217, 119, 94, 90, 227, 170, 239, 116, 54, 25, 42, 70, 217, 204, 155, 139, 18, 69, 110, 193, 252, 4, 82, 240, 190, 175, 116, 36, 72, 125, 110, 160, 22, 228, 2, 157, 101, 111, 43, 65, 169, 10, 121, 188, 128, 148, 212, 205, 255, 220, 196, 28, 53, 234, 108, 86, 119, 15, 182, 127, 208, 243, 3, 141, 233, 135, 161, 99, 131, 202, 90, 59, 18, 175, 167, 99, 95, 76, 153, 111, 11, 169, 128, 162, 167, 236, 27, 109, 111, 154, 248, 244, 212, 221, 91, 230, 62, 2, 212, 245, 234, 113, 169, 93, 154, 32, 234, 127, 81, 59, 49, 46, 99, 73, 168, 70, 93, 159, 111, 25, 42, 86, 16, 255, 192, 38, 131, 225, 222, 68, 154, 226, 28, 235, 123, 149, 147, 52, 176, 17, 25, 21, 98, 213, 38, 229, 158, 115, 209, 86, 67, 36, 103, 40, 217, 244, 158, 225, 248, 183, 97, 199, 81, 5, 144, 44, 233, 81, 255, 187, 168, 34, 223, 81, 201, 15, 112, 240, 93, 230, 244, 236, 221, 222, 18, 23, 21, 180, 21, 204, 43, 94, 27, 184, 111, 245, 253, 157, 245, 59, 166, 69, 228, 70, 147, 169, 133, 2, 37, 131, 50, 185, 68, 179, 172, 243, 235]
and expected output is this :
000000£>Þt¸éKON}Õ06¿¡P$xµÂ9Dö5Éà#“8uØMPÒ*B»çÿ<ÍÖÞÇrxôÞ£Äô%u(Ç2ô0VVð\$÷¹
=¢Æ
µßu.õ²ÍLG8®àdÛ%uSlbK.èÆöêPs¹D6×´:±F?
ñºÐ=¥§¦o`»eú6Á÷0LBÍ’ûô{>ÌÍ=æBnäDÁh¿Uû䥳ÜDëS~é¯{Ïg”cñÐCê8¡3[LýHGDS¤x
°P[³Áhµéaµr¾ÿêeª&8.ÖÏÏÏ+ýÂY00?YÖPÙw^Zãªït6*FÙÌEnÁüRð¾¯t$H}n äeo+A©
y¼ÔÍÿÜÄ5êlVw¶Ðóé¡cÊZ;¯§c_Lo©¢§ìmoøôÔÝ[æ>Ôõêq©]
êQ;1.cI¨F]o*VÿÀ&áÞDâë{4°bÕ&åsÑVC$g(Ùôáø·aÇQ,éQÿ»¨“ßQÉpð]æôìÝÞ´Ì+^¸oõýõ;¦EäF©%2¹D³¬óë
i have been using these function but no gains
String(fullbuffer!)
second code is :
let valuesend = String(bytes: fullbuffer, encoding: String.Encoding.ascii)
the answer i got is this
'000000£>\0\0\u{16}\u{b}\0\0\u{c2}\u{1}\u{c2}\ô{>\u{c2}\u{13}ÌÍ\u{11}=æBnäDÁh¿U\u{1e}ÖPÙw^Zãªït6\u{19}*FÙÌ\u{c2}\u{c2}\u{12}EnÁü\u{4}Rð¾¯t$H}n \u{16}ä\u{2}\u{c2}eo+A©\ny¼\u{c2}\u{c2}ÔÍÿÜÄ\u{1c}5êlVw\u{f}¶\u{7f}Ðó\u{3}\u{c2}é\u{c2}¡c\u{c2}ÊZ;\u{12}¯§c_L\u{c2}o\u{b}©\u{c2}¢§ì\u{1b}mo\u{c2}øôÔÝ[æ>\u{2}Ôõêq©]\u{c2} ê\u{7f}Q;1.cI¨F]\u{c2}o\u{19}*V\u{10}ÿÀ&\u{c2}áÞD\u{c2}â\u{1c}ë{\u{c2}\u{c2}4°\u{11}\u{19}\u{15}bÕ&å\u{c2}sÑVC$g(Ùô\u{c2}áø·aÇQ\u{5}\u{c2},éQÿ»¨\"ßQÉ\u{f}pð]æôìÝÞ\u{12}\u{17}\u{15}´\u{15}Ì+^\u{1b}¸oõý\u{c2}õ;¦EäF\u{c2}©\u{c2}\u{2}%\u{c2}2¹D³¬óë'
let array: [UInt8] = [your data here]
if let output = String(bytes: array, encoding: .ascii) {
print(output)
}
Worked for me, try to explicitly declare your array as an array of UInt8.
I'm currently switching over the Ransack gem. I'm having an issue using the "in" predicate on an integer attribute. My form select looks like this:
<%= form.select :roles_mask_in, options_for_select([['Not Admin', 0..254], ['Admin', 255..255]]), include_blank: "All" %>
An admin has a roles_mask attribute that contains an integer. A 255 indicates that a user is an admin, so I want the Admin selection to only be 255. This part works just fine.
However, when choosing the "Not Admin" choice, it's only returning one result, when it should be returning many (there are many non-admins in this group and their roles_mask integers vary wildly. I decided to use the in predicate to look for numbers within that range. Instead, it is only returning one result, instead of multiple.
Controller (much like all my other controllers that have been changed and have no issue, which leads me to believe this is a predicate, or range issue):
#q = current_company.managers.ransack(params[:q])
#search = #q.result(distinct: true).includes(:user)
A user is included for the association.
I ran this in Ruby console, just to make sure it was returning the correct sql. Manager.ransack(roles_mask_in: 0..244).result.to_sql, which returns the correct SQL (I think):
"SELECT managers``.* FROM managers`` WHERE ``managers.roles_mask`` IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244)"
So the question is: why is it only returning one result, and not all of the managers that should be in that result?
The query is returning only one result because the code above does pass a String instead of a Range Object to ransack due to POST via REST (HTML form).
SIDENOTE: When posting form data from HTML to rails, rails usually takes care of the type-conversion based on types defined in the Model (via the ORM layer).
In the case above you'll have to handle conversion by yourself. (To see this, look what params contains before calling ransack in your controller.)
Type is being cast to String by HTML then passed to ransack which does not know how to handle a String as a Range. To make this work you'll have to convert the string into a range before running the search query like so:
params[:q][:id_in] = string_to_range(params[:q][:roles_mask_in])
with
def string_to_range(rangestr)
rangestr.split('..').inject { |s,e| s.to_i..e.to_i }
end
For more info on the conversion see this SO answer: Best way to convert a Ruby string range to a Range object
I need to create an OAuth2 Authorization Server and using DotNetOpenAuth.
I’m able to receive an Access_Token, but when I want to access a resource from my ResouceServer I get a cryptic error “Bad Data”. I can’t figure out what is bad about the data. (and how to fix it)
It seems that I get a correct token. When I ‘corrupt’ the token, I receive another message.
I call the Resource Server with the following code (this works when I connect to the Google OAuth2 service)
using (WebClient client = new WebClient())
{
client.Headers.Add( HttpRequestHeader.Authorization, "Bearer " + tbToken.Text);
ltext.Text = client.DownloadString(string.Format(#"http://localhost:50299/oauth/userinfo.aspx"));
}
(I know, the token should not be in the Textbox...but first let’s make it work ;-)
Then I access the Resource in userinfo.aspx
protected void Page_Init(object sender, EventArgs e)
{
HttpRequestBase request = new HttpRequestWrapper(Request);
using (var signing = CreateAuthorizationServerSigningServiceProvider())
{
using (var encrypting = CreateResourceServerEncryptionServiceProvider())
{
var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(signing, encrypting));
string[] requiredScopes = { "email" };
try
{
var x = resourceServer.GetAccessToken(request, requiredScopes);
}
catch (Exception ee)
{
//HERE IS THE BAD DATA EXCEPTION
}
}
}
}
internal static RSACryptoServiceProvider CreateResourceServerEncryptionServiceProvider()
{
var resourceServerEncryptionServiceProvider = new RSACryptoServiceProvider();
resourceServerEncryptionServiceProvider.ImportParameters(ResourceServerEncryptionPrivateKey);
return resourceServerEncryptionServiceProvider;
}
internal static RSACryptoServiceProvider CreateAuthorizationServerSigningServiceProvider()
{
var authorizationServerSigningServiceProvider = new RSACryptoServiceProvider();
authorizationServerSigningServiceProvider.ImportParameters(AuthorizationServerSigningPublicKey);
return authorizationServerSigningServiceProvider;
}
//Yeah. I know...this is the example certificate from the demo code
public static readonly RSAParameters AuthorizationServerSigningPublicKey = new RSAParameters
{
Exponent = new byte[] { 1, 0, 1 },
Modulus = new byte[] { 210, 95, 53, 12, 203, 114, 150, 23, 23, 88, 4, 200, 47, 219, 73, 54, 146, 253, 126, 121, 105, 91, 118, 217, 182, 167, 140, 6, 67, 112, 97, 183, 66, 112, 245, 103, 136, 222, 205, 28, 196, 45, 6, 223, 192, 76, 56, 180, 90, 120, 144, 19, 31, 193, 37, 129, 186, 214, 36, 53, 204, 53, 108, 133, 112, 17, 133, 244, 3, 12, 230, 29, 243, 51, 79, 253, 10, 111, 185, 23, 74, 230, 99, 94, 78, 49, 209, 39, 95, 213, 248, 212, 22, 4, 222, 145, 77, 190, 136, 230, 134, 70, 228, 241, 194, 216, 163, 234, 52, 1, 64, 181, 139, 128, 90, 255, 214, 60, 168, 233, 254, 110, 31, 102, 58, 67, 201, 33 },
};
internal static readonly RSAParameters ResourceServerEncryptionPrivateKey = new RSAParameters
{
Exponent = new byte[] { 1, 0, 1 },
Modulus = new byte[] { 166, 175, 117, 169, 211, 251, 45, 215, 55, 53, 202, 65, 153, 155, 92, 219, 235, 243, 61, 170, 101, 250, 221, 214, 239, 175, 238, 175, 239, 20, 144, 72, 227, 221, 4, 219, 32, 225, 101, 96, 18, 33, 117, 176, 110, 123, 109, 23, 29, 85, 93, 50, 129, 163, 113, 57, 122, 212, 141, 145, 17, 31, 67, 165, 181, 91, 117, 23, 138, 251, 198, 132, 188, 213, 10, 157, 116, 229, 48, 168, 8, 127, 28, 156, 239, 124, 117, 36, 232, 100, 222, 23, 52, 186, 239, 5, 63, 207, 185, 16, 137, 73, 137, 147, 252, 71, 9, 239, 113, 27, 88, 255, 91, 56, 192, 142, 210, 21, 34, 81, 204, 239, 57, 60, 140, 249, 15, 101 },
P = new byte[] { 227, 25, 96, 71, 220, 99, 11, 55, 15, 241, 153, 20, 32, 213, 68, 127, 246, 162, 153, 204, 98, 26, 10, 99, 46, 189, 35, 18, 162, 180, 184, 134, 230, 198, 156, 87, 52, 174, 74, 155, 163, 204, 252, 51, 232, 189, 135, 172, 88, 24, 52, 174, 72, 157, 81, 90, 118, 59, 142, 154, 152, 201, 62, 177 },
Q = new byte[] { 187, 229, 223, 233, 118, 20, 5, 251, 85, 8, 196, 3, 220, 232, 38, 159, 15, 95, 174, 162, 36, 13, 138, 239, 16, 85, 220, 104, 4, 162, 174, 160, 234, 133, 156, 33, 117, 139, 22, 112, 108, 214, 97, 178, 100, 191, 13, 177, 164, 30, 124, 48, 33, 118, 21, 137, 38, 59, 191, 13, 183, 5, 16, 245 },
DP = new byte[] { 225, 112, 117, 117, 160, 191, 233, 136, 53, 153, 158, 94, 174, 225, 71, 104, 200, 75, 77, 229, 232, 148, 245, 46, 212, 93, 9, 142, 28, 90, 206, 187, 140, 40, 41, 87, 32, 130, 204, 169, 136, 135, 154, 237, 100, 227, 144, 229, 115, 102, 68, 21, 167, 28, 20, 128, 122, 210, 80, 148, 3, 139, 243, 97 },
DQ = new byte[] { 133, 252, 100, 207, 232, 184, 92, 143, 157, 82, 115, 220, 65, 81, 118, 0, 228, 136, 153, 81, 219, 157, 160, 157, 218, 171, 47, 81, 41, 69, 12, 123, 136, 224, 159, 182, 40, 72, 119, 70, 210, 5, 137, 131, 25, 94, 55, 152, 157, 236, 115, 40, 43, 36, 54, 53, 39, 131, 97, 56, 153, 114, 206, 101 },
InverseQ = new byte[] { 129, 119, 84, 118, 29, 35, 194, 186, 96, 169, 7, 7, 200, 22, 187, 34, 72, 131, 200, 246, 79, 120, 49, 242, 8, 220, 74, 114, 195, 95, 90, 108, 80, 2, 212, 71, 125, 100, 184, 77, 203, 236, 64, 122, 108, 212, 150, 129, 66, 248, 218, 3, 186, 71, 213, 236, 142, 66, 33, 196, 150, 216, 138, 114 },
D = new byte[] { 94, 20, 94, 119, 18, 92, 141, 13, 17, 238, 92, 80, 22, 96, 232, 82, 128, 164, 115, 195, 191, 119, 142, 202, 135, 210, 103, 8, 10, 11, 51, 60, 208, 207, 168, 179, 253, 164, 250, 80, 245, 42, 201, 128, 97, 123, 108, 161, 69, 63, 47, 49, 24, 150, 165, 139, 105, 214, 154, 104, 172, 159, 86, 208, 64, 134, 158, 156, 234, 125, 140, 210, 3, 32, 60, 28, 62, 154, 198, 21, 132, 191, 236, 10, 158, 12, 247, 159, 177, 77, 178, 53, 238, 95, 165, 9, 200, 28, 148, 242, 35, 70, 189, 121, 169, 248, 97, 91, 111, 45, 103, 1, 167, 220, 67, 250, 175, 89, 122, 238, 192, 144, 142, 248, 198, 101, 96, 129 },
};
I
A (very good) friend of did take a look.
And did say: “didn’t you forget to import the ResourceServerEncryptionPublicKey in the CreateAccesstoken?”
By creating a minimal working example, I did comment out a little too much.
The problem is solved, with adding the following line in the CreateAccessToken function:
accessToken.ResourceServerEncryptionKey.ImportParameters(ResourceServerEncryptionPublicKey);
I am working on a OAuth 2.0 server and client implementation. I am using "http://www.dotnetopenauth.net/" CTP version. In one of the samples, the code is creating a class inheriting from "ServiceAuthorizationManager" in that they are overwriting method "CheckAccessCore" in the method they are using operationContext.IncomingMessageHeaders.Action to verify the scope of the call. I think this information comes in SOAP message. Now, I want to create an ASP.net MVC resource server, In that I wrote a Authorize attribute. But, I am not able to figure out a replacement of "operationContext.IncomingMessageHeaders.Action". Following is the code of my "OAuthAuthorizedAttribute"
public class OAuthAuthorizedAttribute : ActionFilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext) {
//First verify the access code
var principal = VerifyOAuth2(HttpContext.Current.Request);
//second check the role
if (principal == null)
throw new ApplicationException("Access Token Invalid");
if (!principal.IsInRole(filterContext.HttpContext.Request.Headers.ToString()))
throw new ApplicationException("User doesn't have permission");
}
private IPrincipal VerifyOAuth2(HttpRequest httpRequest) {
// for this sample where the auth server and resource server are the same site,
// we use the same public/private key.
using (var signing = this.CreateAuthorizationServerSigningServiceProvider()) {
using (var encrypting = this.CreateResourceServerEncryptionServiceProvider()) {
var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(signing, encrypting));
IPrincipal result;
var error = resourceServer.VerifyAccess(new HttpRequestInfo(httpRequest), out result);
// TODO: return the prepared error code.
return error != null ? null : result;
}
}
}
//#if SAMPLESONLY
/// <summary>
/// The FOR SAMPLE ONLY hard-coded public key of the authorization server that is used to verify the signature on access tokens.
/// </summary>
/// <remarks>
/// In a real app, the authorization server public key would likely come from the server's HTTPS certificate,
/// but in any case would be determined by the authorization server and its policies.
/// The hard-coded value used here is so this sample works well with the OAuthAuthorizationServer sample,
/// which has the corresponding sample private key.
/// </remarks>
public readonly RSAParameters AuthorizationServerSigningPublicKey = new RSAParameters {
Exponent = new byte[] { 1, 0, 1 },
Modulus = new byte[] { 210, 95, 53, 12, 203, 114, 150, 23, 23, 88, 4, 200, 47, 219, 73, 54, 146, 253, 126, 121, 105, 91, 118, 217, 182, 167, 140, 6, 67, 112, 97, 183, 66, 112, 245, 103, 136, 222, 205, 28, 196, 45, 6, 223, 192, 76, 56, 180, 90, 120, 144, 19, 31, 193, 37, 129, 186, 214, 36, 53, 204, 53, 108, 133, 112, 17, 133, 244, 3, 12, 230, 29, 243, 51, 79, 253, 10, 111, 185, 23, 74, 230, 99, 94, 78, 49, 209, 39, 95, 213, 248, 212, 22, 4, 222, 145, 77, 190, 136, 230, 134, 70, 228, 241, 194, 216, 163, 234, 52, 1, 64, 181, 139, 128, 90, 255, 214, 60, 168, 233, 254, 110, 31, 102, 58, 67, 201, 33 },
};
//#else
// [Obsolete("You must use a real key for a real app.", true)]
// public static readonly RSAParameters AuthorizationServerSigningPublicKey = new RSAParameters();
//#endif
//#if SAMPLESONLY
/// <summary>
/// The FOR SAMPLE ONLY hard-coded private key used to decrypt access tokens intended for this resource server.
/// </summary>
/// <remarks>
/// In a real app, the resource server would likely use its own HTTPS certificate or some other certificate stored securely
/// on the server rather than hard-coded in compiled code for security and ease of changing the certificate in case it was compromised.
/// </remarks>
internal readonly RSAParameters ResourceServerEncryptionPrivateKey = new RSAParameters {
Exponent = new byte[] { 1, 0, 1 },
Modulus = new byte[] { 166, 175, 117, 169, 211, 251, 45, 215, 55, 53, 202, 65, 153, 155, 92, 219, 235, 243, 61, 170, 101, 250, 221, 214, 239, 175, 238, 175, 239, 20, 144, 72, 227, 221, 4, 219, 32, 225, 101, 96, 18, 33, 117, 176, 110, 123, 109, 23, 29, 85, 93, 50, 129, 163, 113, 57, 122, 212, 141, 145, 17, 31, 67, 165, 181, 91, 117, 23, 138, 251, 198, 132, 188, 213, 10, 157, 116, 229, 48, 168, 8, 127, 28, 156, 239, 124, 117, 36, 232, 100, 222, 23, 52, 186, 239, 5, 63, 207, 185, 16, 137, 73, 137, 147, 252, 71, 9, 239, 113, 27, 88, 255, 91, 56, 192, 142, 210, 21, 34, 81, 204, 239, 57, 60, 140, 249, 15, 101 },
P = new byte[] { 227, 25, 96, 71, 220, 99, 11, 55, 15, 241, 153, 20, 32, 213, 68, 127, 246, 162, 153, 204, 98, 26, 10, 99, 46, 189, 35, 18, 162, 180, 184, 134, 230, 198, 156, 87, 52, 174, 74, 155, 163, 204, 252, 51, 232, 189, 135, 172, 88, 24, 52, 174, 72, 157, 81, 90, 118, 59, 142, 154, 152, 201, 62, 177 },
Q = new byte[] { 187, 229, 223, 233, 118, 20, 5, 251, 85, 8, 196, 3, 220, 232, 38, 159, 15, 95, 174, 162, 36, 13, 138, 239, 16, 85, 220, 104, 4, 162, 174, 160, 234, 133, 156, 33, 117, 139, 22, 112, 108, 214, 97, 178, 100, 191, 13, 177, 164, 30, 124, 48, 33, 118, 21, 137, 38, 59, 191, 13, 183, 5, 16, 245 },
DP = new byte[] { 225, 112, 117, 117, 160, 191, 233, 136, 53, 153, 158, 94, 174, 225, 71, 104, 200, 75, 77, 229, 232, 148, 245, 46, 212, 93, 9, 142, 28, 90, 206, 187, 140, 40, 41, 87, 32, 130, 204, 169, 136, 135, 154, 237, 100, 227, 144, 229, 115, 102, 68, 21, 167, 28, 20, 128, 122, 210, 80, 148, 3, 139, 243, 97 },
DQ = new byte[] { 133, 252, 100, 207, 232, 184, 92, 143, 157, 82, 115, 220, 65, 81, 118, 0, 228, 136, 153, 81, 219, 157, 160, 157, 218, 171, 47, 81, 41, 69, 12, 123, 136, 224, 159, 182, 40, 72, 119, 70, 210, 5, 137, 131, 25, 94, 55, 152, 157, 236, 115, 40, 43, 36, 54, 53, 39, 131, 97, 56, 153, 114, 206, 101 },
InverseQ = new byte[] { 129, 119, 84, 118, 29, 35, 194, 186, 96, 169, 7, 7, 200, 22, 187, 34, 72, 131, 200, 246, 79, 120, 49, 242, 8, 220, 74, 114, 195, 95, 90, 108, 80, 2, 212, 71, 125, 100, 184, 77, 203, 236, 64, 122, 108, 212, 150, 129, 66, 248, 218, 3, 186, 71, 213, 236, 142, 66, 33, 196, 150, 216, 138, 114 },
D = new byte[] { 94, 20, 94, 119, 18, 92, 141, 13, 17, 238, 92, 80, 22, 96, 232, 82, 128, 164, 115, 195, 191, 119, 142, 202, 135, 210, 103, 8, 10, 11, 51, 60, 208, 207, 168, 179, 253, 164, 250, 80, 245, 42, 201, 128, 97, 123, 108, 161, 69, 63, 47, 49, 24, 150, 165, 139, 105, 214, 154, 104, 172, 159, 86, 208, 64, 134, 158, 156, 234, 125, 140, 210, 3, 32, 60, 28, 62, 154, 198, 21, 132, 191, 236, 10, 158, 12, 247, 159, 177, 77, 178, 53, 238, 95, 165, 9, 200, 28, 148, 242, 35, 70, 189, 121, 169, 248, 97, 91, 111, 45, 103, 1, 167, 220, 67, 250, 175, 89, 122, 238, 192, 144, 142, 248, 198, 101, 96, 129 },
};
//#else
//[Obsolete("You must use a real key for a real app.", true)]
//internal static readonly RSAParameters ResourceServerEncryptionPrivateKey = new RSAParameters();
//#endif
/// <summary>
/// Creates the crypto service provider for this resource server that contains the private key used to decrypt an access token.
/// </summary>
/// <returns>An RSA crypto service provider.</returns>
internal RSACryptoServiceProvider CreateResourceServerEncryptionServiceProvider() {
var resourceServerEncryptionServiceProvider = new RSACryptoServiceProvider();
resourceServerEncryptionServiceProvider.ImportParameters(ResourceServerEncryptionPrivateKey);
return resourceServerEncryptionServiceProvider;
}
/// <summary>
/// Creates the crypto service provider for the authorization server that contains the public key used to verify an access token signature.
/// </summary>
/// <returns>An RSA crypto service provider.</returns>
internal RSACryptoServiceProvider CreateAuthorizationServerSigningServiceProvider() {
var authorizationServerSigningServiceProvider = new RSACryptoServiceProvider();
authorizationServerSigningServiceProvider.ImportParameters(AuthorizationServerSigningPublicKey);
return authorizationServerSigningServiceProvider;
}
}
Action is related only to SOAP message processing - it identifies operation to be executed to process incoming SOAP request. Equivalent in MVC is routing mechanism which maps requested URL to actions in controllers. When implementing ActionFilter you already have these data available. All virtual methods defined in ActionFilterAttribute base class accepts ActionExecutedContext which has ActionDescriptor property - it will give you information about currently evaluated action and controller. AuthorizationContext passed to OnAuthorization method also contains ActionDescriptor property.